blob: df1ce8cbbd3625d10e4660eb14c02ea9496c513b [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 Hamano7426eb72007-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 Hamano7426eb72007-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 Levedahl40b87ff2007-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
Junio C Hamanoe9937d22007-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
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500440
441 # possibly use assumed geometry
442 if {![info exists geometry(topheight)]} {
443 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}]
447 set geometry(canv) [expr {40 * $charspc}]
448 set geometry(canv2) [expr {20 * $charspc}]
449 set geometry(canv3) [expr {20 * $charspc}]
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000450 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500451
452 # the upper half will have a paned window, a scroll bar to the right, and some stuff below
453 frame .tf -height $geometry(topheight) -width $geometry(topwidth)
454 frame .tf.histframe
455 panedwindow .tf.histframe.pwclist -orient horizontal -sashpad 0 -handlesize 4
456
457 # create three canvases
458 set cscroll .tf.histframe.csb
459 set canv .tf.histframe.pwclist.canv
460 canvas $canv -width $geometry(canv) \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000461 -background $bgcolor -bd 0 \
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100462 -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500463 .tf.histframe.pwclist add $canv
464 set canv2 .tf.histframe.pwclist.canv2
465 canvas $canv2 -width $geometry(canv2) \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000466 -background $bgcolor -bd 0 -yscrollincr $linespc
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500467 .tf.histframe.pwclist add $canv2
468 set canv3 .tf.histframe.pwclist.canv3
469 canvas $canv3 -width $geometry(canv3) \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000470 -background $bgcolor -bd 0 -yscrollincr $linespc
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500471 .tf.histframe.pwclist add $canv3
Paul Mackerras98f350e2005-05-15 05:56:51 +0000472
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500473 # a scroll bar to rule them
474 scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
475 pack $cscroll -side right -fill y
476 bind .tf.histframe.pwclist <Configure> {resizeclistpanes %W %w}
477 lappend bglist $canv $canv2 $canv3
478 pack .tf.histframe.pwclist -fill both -expand 1 -side left
479
480 # we have two button bars at bottom of top frame. Bar 1
481 frame .tf.bar
482 frame .tf.lbar -height 15
483
484 set sha1entry .tf.bar.sha1
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000485 set entries $sha1entry
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500486 set sha1but .tf.bar.sha1label
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000487 button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
Keith Packard4840be62006-04-04 00:19:45 -0700488 -command gotocommit -width 8 -font $uifont
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000489 $sha1but conf -disabledforeground [$sha1but cget -foreground]
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500490 pack .tf.bar.sha1label -side left
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000491 entry $sha1entry -width 40 -font $textfont -textvariable sha1string
492 trace add variable sha1string write sha1change
Paul Mackerras98f350e2005-05-15 05:56:51 +0000493 pack $sha1entry -side left -pady 2
Paul Mackerrasd6982062005-08-06 22:06:06 +1000494
495 image create bitmap bm-left -data {
496 #define left_width 16
497 #define left_height 16
498 static unsigned char left_bits[] = {
499 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
500 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
501 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
502 }
503 image create bitmap bm-right -data {
504 #define right_width 16
505 #define right_height 16
506 static unsigned char right_bits[] = {
507 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
508 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
509 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
510 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500511 button .tf.bar.leftbut -image bm-left -command goback \
Paul Mackerrasd6982062005-08-06 22:06:06 +1000512 -state disabled -width 26
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500513 pack .tf.bar.leftbut -side left -fill y
514 button .tf.bar.rightbut -image bm-right -command goforw \
Paul Mackerrasd6982062005-08-06 22:06:06 +1000515 -state disabled -width 26
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500516 pack .tf.bar.rightbut -side left -fill y
Paul Mackerrasd6982062005-08-06 22:06:06 +1000517
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500518 button .tf.bar.findbut -text "Find" -command dofind -font $uifont
519 pack .tf.bar.findbut -side left
Paul Mackerras98f350e2005-05-15 05:56:51 +0000520 set findstring {}
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500521 set fstring .tf.bar.findstring
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000522 lappend entries $fstring
Paul Mackerras908c3582006-05-20 09:38:11 +1000523 entry $fstring -width 30 -font $textfont -textvariable findstring
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000524 trace add variable findstring write find_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500525 pack $fstring -side left -expand 1 -fill x -in .tf.bar
Paul Mackerras98f350e2005-05-15 05:56:51 +0000526 set findtype Exact
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500527 set findtypemenu [tk_optionMenu .tf.bar.findtype \
528 findtype Exact IgnCase Regexp]
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000529 trace add variable findtype write find_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500530 .tf.bar.findtype configure -font $uifont
531 .tf.bar.findtype.menu configure -font $uifont
Paul Mackerras98f350e2005-05-15 05:56:51 +0000532 set findloc "All fields"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500533 tk_optionMenu .tf.bar.findloc findloc "All fields" Headline \
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000534 Comments Author Committer
535 trace add variable findloc write find_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500536 .tf.bar.findloc configure -font $uifont
537 .tf.bar.findloc.menu configure -font $uifont
538 pack .tf.bar.findloc -side right
539 pack .tf.bar.findtype -side right
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000540
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500541 # build up the bottom bar of upper window
542 label .tf.lbar.flabel -text "Highlight: Commits " \
543 -font $uifont
544 pack .tf.lbar.flabel -side left -fill y
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000545 set gdttype "touching paths:"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500546 set gm [tk_optionMenu .tf.lbar.gdttype gdttype "touching paths:" \
547 "adding/removing string:"]
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000548 trace add variable gdttype write hfiles_change
549 $gm conf -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500550 .tf.lbar.gdttype conf -font $uifont
551 pack .tf.lbar.gdttype -side left -fill y
552 entry .tf.lbar.fent -width 25 -font $textfont \
Paul Mackerras908c3582006-05-20 09:38:11 +1000553 -textvariable highlight_files
554 trace add variable highlight_files write hfiles_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500555 lappend entries .tf.lbar.fent
556 pack .tf.lbar.fent -side left -fill x -expand 1
557 label .tf.lbar.vlabel -text " OR in view" -font $uifont
558 pack .tf.lbar.vlabel -side left -fill y
Paul Mackerras908c3582006-05-20 09:38:11 +1000559 global viewhlmenu selectedhlview
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500560 set viewhlmenu [tk_optionMenu .tf.lbar.vhl selectedhlview None]
Paul Mackerras3cd204e2006-11-23 21:06:16 +1100561 $viewhlmenu entryconf None -command delvhighlight
Paul Mackerras63b79192006-05-20 21:31:52 +1000562 $viewhlmenu conf -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500563 .tf.lbar.vhl conf -font $uifont
564 pack .tf.lbar.vhl -side left -fill y
565 label .tf.lbar.rlabel -text " OR " -font $uifont
566 pack .tf.lbar.rlabel -side left -fill y
Paul Mackerras164ff272006-05-29 19:50:02 +1000567 global highlight_related
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500568 set m [tk_optionMenu .tf.lbar.relm highlight_related None \
569 "Descendent" "Not descendent" "Ancestor" "Not ancestor"]
Paul Mackerras164ff272006-05-29 19:50:02 +1000570 $m conf -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500571 .tf.lbar.relm conf -font $uifont
Paul Mackerras164ff272006-05-29 19:50:02 +1000572 trace add variable highlight_related write vrel_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500573 pack .tf.lbar.relm -side left -fill y
Paul Mackerras908c3582006-05-20 09:38:11 +1000574
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500575 # Finish putting the upper half of the viewer together
576 pack .tf.lbar -in .tf -side bottom -fill x
577 pack .tf.bar -in .tf -side bottom -fill x
578 pack .tf.histframe -fill both -side top -expand 1
579 .ctop add .tf
580
581 # now build up the bottom
582 panedwindow .pwbottom -orient horizontal
583
584 # lower left, a text box over search bar, scroll bar to the right
585 # if we know window height, then that will set the lower text height, otherwise
586 # we set lower text height which will drive window height
587 if {[info exists geometry(main)]} {
588 frame .bleft -width $geometry(botwidth)
589 } else {
590 frame .bleft -width $geometry(botwidth) -height $geometry(botheight)
591 }
592 frame .bleft.top
593
594 button .bleft.top.search -text "Search" -command dosearch \
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000595 -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500596 pack .bleft.top.search -side left -padx 5
597 set sstring .bleft.top.sstring
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000598 entry $sstring -width 20 -font $textfont -textvariable searchstring
599 lappend entries $sstring
600 trace add variable searchstring write incrsearch
601 pack $sstring -side left -expand 1 -fill x
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500602 set ctext .bleft.ctext
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000603 text $ctext -background $bgcolor -foreground $fgcolor \
604 -state disabled -font $textfont \
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000605 -yscrollcommand scrolltext -wrap none
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500606 scrollbar .bleft.sb -command "$ctext yview"
607 pack .bleft.top -side top -fill x
608 pack .bleft.sb -side right -fill y
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000609 pack $ctext -side left -fill both -expand 1
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000610 lappend bglist $ctext
611 lappend fglist $ctext
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000612
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400613 $ctext tag conf comment -wrap $wrapcomment
Paul Mackerrasf0654862005-07-18 14:29:03 -0400614 $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000615 $ctext tag conf hunksep -fore [lindex $diffcolors 2]
616 $ctext tag conf d0 -fore [lindex $diffcolors 0]
617 $ctext tag conf d1 -fore [lindex $diffcolors 1]
Paul Mackerras712fcc02005-11-30 09:28:16 +1100618 $ctext tag conf m0 -fore red
619 $ctext tag conf m1 -fore blue
620 $ctext tag conf m2 -fore green
621 $ctext tag conf m3 -fore purple
622 $ctext tag conf m4 -fore brown
Paul Mackerrasb77b0272006-02-07 09:13:52 +1100623 $ctext tag conf m5 -fore "#009090"
624 $ctext tag conf m6 -fore magenta
625 $ctext tag conf m7 -fore "#808000"
626 $ctext tag conf m8 -fore "#009000"
627 $ctext tag conf m9 -fore "#ff0080"
628 $ctext tag conf m10 -fore cyan
629 $ctext tag conf m11 -fore "#b07070"
630 $ctext tag conf m12 -fore "#70b0f0"
631 $ctext tag conf m13 -fore "#70f0b0"
632 $ctext tag conf m14 -fore "#f0b070"
633 $ctext tag conf m15 -fore "#ff70b0"
Paul Mackerras712fcc02005-11-30 09:28:16 +1100634 $ctext tag conf mmax -fore darkgrey
Paul Mackerrasb77b0272006-02-07 09:13:52 +1100635 set mergemax 16
Paul Mackerras712fcc02005-11-30 09:28:16 +1100636 $ctext tag conf mresult -font [concat $textfont bold]
637 $ctext tag conf msep -font [concat $textfont bold]
638 $ctext tag conf found -back yellow
Paul Mackerrase5c2d852005-05-11 23:44:54 +0000639
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500640 .pwbottom add .bleft
641
642 # lower right
643 frame .bright
644 frame .bright.mode
645 radiobutton .bright.mode.patch -text "Patch" \
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000646 -command reselectline -variable cmitmode -value "patch"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500647 radiobutton .bright.mode.tree -text "Tree" \
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000648 -command reselectline -variable cmitmode -value "tree"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500649 grid .bright.mode.patch .bright.mode.tree -sticky ew
650 pack .bright.mode -side top -fill x
651 set cflist .bright.cfiles
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000652 set indent [font measure $mainfont "nn"]
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500653 text $cflist \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000654 -background $bgcolor -foreground $fgcolor \
655 -font $mainfont \
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000656 -tabs [list $indent [expr {2 * $indent}]] \
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500657 -yscrollcommand ".bright.sb set" \
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000658 -cursor [. cget -cursor] \
659 -spacing1 1 -spacing3 1
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000660 lappend bglist $cflist
661 lappend fglist $cflist
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500662 scrollbar .bright.sb -command "$cflist yview"
663 pack .bright.sb -side right -fill y
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000664 pack $cflist -side left -fill both -expand 1
Paul Mackerras89b11d32006-05-02 19:55:31 +1000665 $cflist tag configure highlight \
666 -background [$cflist cget -selectbackground]
Paul Mackerras63b79192006-05-20 21:31:52 +1000667 $cflist tag configure bold -font [concat $mainfont bold]
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000668
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500669 .pwbottom add .bright
670 .ctop add .pwbottom
Paul Mackerras1db95b02005-05-09 04:08:39 +0000671
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500672 # restore window position if known
673 if {[info exists geometry(main)]} {
674 wm geometry . "$geometry(main)"
675 }
676
677 bind .pwbottom <Configure> {resizecdetpanes %W %w}
678 pack .ctop -fill both -expand 1
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000679 bindall <1> {selcanvline %W %x %y}
680 #bindall <B1-Motion> {selcanvline %W %x %y}
Paul Mackerrascfb45632005-05-31 12:14:42 +0000681 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
682 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
Paul Mackerrasbe0cd092006-03-31 09:55:11 +1100683 bindall <2> "canvscan mark %W %x %y"
684 bindall <B2-Motion> "canvscan dragto %W %x %y"
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000685 bindkey <Home> selfirstline
686 bindkey <End> sellastline
Paul Mackerras17386062005-05-18 22:51:00 +0000687 bind . <Key-Up> "selnextline -1"
688 bind . <Key-Down> "selnextline 1"
Paul Mackerras4e7d6772006-05-30 21:33:07 +1000689 bind . <Shift-Key-Up> "next_highlight -1"
690 bind . <Shift-Key-Down> "next_highlight 1"
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000691 bindkey <Key-Right> "goforw"
692 bindkey <Key-Left> "goback"
693 bind . <Key-Prior> "selnextpage -1"
694 bind . <Key-Next> "selnextpage 1"
695 bind . <Control-Home> "allcanvs yview moveto 0.0"
696 bind . <Control-End> "allcanvs yview moveto 1.0"
697 bind . <Control-Key-Up> "allcanvs yview scroll -1 units"
698 bind . <Control-Key-Down> "allcanvs yview scroll 1 units"
699 bind . <Control-Key-Prior> "allcanvs yview scroll -1 pages"
700 bind . <Control-Key-Next> "allcanvs yview scroll 1 pages"
Paul Mackerrascfb45632005-05-31 12:14:42 +0000701 bindkey <Key-Delete> "$ctext yview scroll -1 pages"
702 bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
703 bindkey <Key-space> "$ctext yview scroll 1 pages"
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000704 bindkey p "selnextline -1"
705 bindkey n "selnextline 1"
Robert Suetterlin6e2dda32005-09-22 10:07:36 +1000706 bindkey z "goback"
707 bindkey x "goforw"
708 bindkey i "selnextline -1"
709 bindkey k "selnextline 1"
710 bindkey j "goback"
711 bindkey l "goforw"
Paul Mackerrascfb45632005-05-31 12:14:42 +0000712 bindkey b "$ctext yview scroll -1 pages"
713 bindkey d "$ctext yview scroll 18 units"
714 bindkey u "$ctext yview scroll -18 units"
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400715 bindkey / {findnext 1}
716 bindkey <Key-Return> {findnext 0}
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000717 bindkey ? findprev
Paul Mackerras39ad8572005-05-19 12:35:53 +0000718 bindkey f nextfile
Paul Mackerras1d10f362005-05-15 12:55:47 +0000719 bind . <Control-q> doquit
Paul Mackerras98f350e2005-05-15 05:56:51 +0000720 bind . <Control-f> dofind
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400721 bind . <Control-g> {findnext 0}
Paul Mackerras1902c272006-05-25 21:25:13 +1000722 bind . <Control-r> dosearchback
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000723 bind . <Control-s> dosearch
Paul Mackerras1d10f362005-05-15 12:55:47 +0000724 bind . <Control-equal> {incrfont 1}
725 bind . <Control-KP_Add> {incrfont 1}
726 bind . <Control-minus> {incrfont -1}
727 bind . <Control-KP_Subtract> {incrfont -1}
Mark Levedahlb6047c52007-02-08 22:22:24 -0500728 wm protocol . WM_DELETE_WINDOW doquit
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000729 bind . <Button-1> "click %W"
Paul Mackerras17386062005-05-18 22:51:00 +0000730 bind $fstring <Key-Return> dofind
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000731 bind $sha1entry <Key-Return> gotocommit
Paul Mackerrasee3dc722005-06-25 16:37:13 +1000732 bind $sha1entry <<PasteSelection>> clearsha1
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000733 bind $cflist <1> {sel_flist %W %x %y; break}
734 bind $cflist <B1-Motion> {sel_flist %W %x %y; break}
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000735 bind $cflist <ButtonRelease-1> {treeclick %W %x %y}
Paul Mackerrasea13cba2005-06-16 10:54:04 +0000736
737 set maincursor [. cget -cursor]
738 set textcursor [$ctext cget -cursor]
Paul Mackerras94a2eed2005-08-07 15:27:57 +1000739 set curtextcursor $textcursor
Paul Mackerras84ba7342005-06-17 00:12:26 +0000740
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000741 set rowctxmenu .rowctxmenu
742 menu $rowctxmenu -tearoff 0
743 $rowctxmenu add command -label "Diff this -> selected" \
744 -command {diffvssel 0}
745 $rowctxmenu add command -label "Diff selected -> this" \
746 -command {diffvssel 1}
Paul Mackerras74daedb2005-06-27 19:27:32 +1000747 $rowctxmenu add command -label "Make patch" -command mkpatch
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +1000748 $rowctxmenu add command -label "Create tag" -command mktag
Paul Mackerras4a2139f2005-06-29 09:47:48 +1000749 $rowctxmenu add command -label "Write commit to file" -command writecommit
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +1000750 $rowctxmenu add command -label "Create new branch" -command mkbranch
Paul Mackerrasca6d8f52006-08-06 21:08:05 +1000751 $rowctxmenu add command -label "Cherry-pick this commit" \
752 -command cherrypick
Paul Mackerras10299152006-08-02 09:52:01 +1000753
754 set headctxmenu .headctxmenu
755 menu $headctxmenu -tearoff 0
756 $headctxmenu add command -label "Check out this branch" \
757 -command cobranch
758 $headctxmenu add command -label "Remove this branch" \
759 -command rmbranch
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000760}
761
Paul Mackerrasbe0cd092006-03-31 09:55:11 +1100762# mouse-2 makes all windows scan vertically, but only the one
763# the cursor is in scans horizontally
764proc canvscan {op w x y} {
765 global canv canv2 canv3
766 foreach c [list $canv $canv2 $canv3] {
767 if {$c == $w} {
768 $c scan $op $x $y
769 } else {
770 $c scan $op 0 $y
771 }
772 }
773}
774
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100775proc scrollcanv {cscroll f0 f1} {
776 $cscroll set $f0 $f1
777 drawfrac $f0 $f1
Paul Mackerras908c3582006-05-20 09:38:11 +1000778 flushhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100779}
780
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000781# when we make a key binding for the toplevel, make sure
782# it doesn't get triggered when that key is pressed in the
783# find string entry widget.
784proc bindkey {ev script} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000785 global entries
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000786 bind . $ev $script
787 set escript [bind Entry $ev]
788 if {$escript == {}} {
789 set escript [bind Entry <Key>]
790 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000791 foreach e $entries {
792 bind $e $ev "$escript; break"
793 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000794}
795
796# set the focus back to the toplevel for any click outside
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000797# the entry widgets
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000798proc click {w} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000799 global entries
800 foreach e $entries {
801 if {$w == $e} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000802 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000803 focus .
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000804}
805
806proc savestuff {w} {
Keith Packard4840be62006-04-04 00:19:45 -0700807 global canv canv2 canv3 ctext cflist mainfont textfont uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +1100808 global stuffsaved findmergefiles maxgraphpct
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +1000809 global maxwidth showneartags
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000810 global viewname viewfiles viewargs viewperm nextviewnum
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400811 global cmitmode wrapcomment
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000812 global colors bgcolor fgcolor diffcolors
Paul Mackerras4ef17532005-07-27 22:16:51 -0500813
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000814 if {$stuffsaved} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000815 if {![winfo viewable .]} return
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000816 catch {
817 set f [open "~/.gitk-new" w]
Paul Mackerrasf0654862005-07-18 14:29:03 -0400818 puts $f [list set mainfont $mainfont]
819 puts $f [list set textfont $textfont]
Keith Packard4840be62006-04-04 00:19:45 -0700820 puts $f [list set uifont $uifont]
Paul Mackerrasf0654862005-07-18 14:29:03 -0400821 puts $f [list set findmergefiles $findmergefiles]
Paul Mackerras8d858d12005-08-05 09:52:16 +1000822 puts $f [list set maxgraphpct $maxgraphpct]
Paul Mackerras04c13d32005-08-19 10:22:24 +1000823 puts $f [list set maxwidth $maxwidth]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000824 puts $f [list set cmitmode $cmitmode]
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400825 puts $f [list set wrapcomment $wrapcomment]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +1000826 puts $f [list set showneartags $showneartags]
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000827 puts $f [list set bgcolor $bgcolor]
828 puts $f [list set fgcolor $fgcolor]
829 puts $f [list set colors $colors]
830 puts $f [list set diffcolors $diffcolors]
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500831
Mark Levedahlb6047c52007-02-08 22:22:24 -0500832 puts $f "set geometry(main) [wm geometry .]"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500833 puts $f "set geometry(topwidth) [winfo width .tf]"
834 puts $f "set geometry(topheight) [winfo height .tf]"
Mark Levedahlb6047c52007-02-08 22:22:24 -0500835 puts $f "set geometry(canv) [winfo width $canv]"
836 puts $f "set geometry(canv2) [winfo width $canv2]"
837 puts $f "set geometry(canv3) [winfo width $canv3]"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500838 puts $f "set geometry(botwidth) [winfo width .bleft]"
839 puts $f "set geometry(botheight) [winfo height .bleft]"
840
Paul Mackerrasa90a6d22006-04-25 17:12:46 +1000841 puts -nonewline $f "set permviews {"
842 for {set v 0} {$v < $nextviewnum} {incr v} {
843 if {$viewperm($v)} {
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000844 puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v)]}"
Paul Mackerrasa90a6d22006-04-25 17:12:46 +1000845 }
846 }
847 puts $f "}"
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000848 close $f
849 file rename -force "~/.gitk-new" "~/.gitk"
850 }
851 set stuffsaved 1
Paul Mackerras1db95b02005-05-09 04:08:39 +0000852}
853
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000854proc resizeclistpanes {win w} {
855 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +1100856 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000857 set s0 [$win sash coord 0]
858 set s1 [$win sash coord 1]
859 if {$w < 60} {
860 set sash0 [expr {int($w/2 - 2)}]
861 set sash1 [expr {int($w*5/6 - 2)}]
862 } else {
863 set factor [expr {1.0 * $w / $oldwidth($win)}]
864 set sash0 [expr {int($factor * [lindex $s0 0])}]
865 set sash1 [expr {int($factor * [lindex $s1 0])}]
866 if {$sash0 < 30} {
867 set sash0 30
868 }
869 if {$sash1 < $sash0 + 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800870 set sash1 [expr {$sash0 + 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000871 }
872 if {$sash1 > $w - 10} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800873 set sash1 [expr {$w - 10}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000874 if {$sash0 > $sash1 - 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800875 set sash0 [expr {$sash1 - 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000876 }
877 }
878 }
879 $win sash place 0 $sash0 [lindex $s0 1]
880 $win sash place 1 $sash1 [lindex $s1 1]
881 }
882 set oldwidth($win) $w
883}
884
885proc resizecdetpanes {win w} {
886 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +1100887 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000888 set s0 [$win sash coord 0]
889 if {$w < 60} {
890 set sash0 [expr {int($w*3/4 - 2)}]
891 } else {
892 set factor [expr {1.0 * $w / $oldwidth($win)}]
893 set sash0 [expr {int($factor * [lindex $s0 0])}]
894 if {$sash0 < 45} {
895 set sash0 45
896 }
897 if {$sash0 > $w - 15} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800898 set sash0 [expr {$w - 15}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000899 }
900 }
901 $win sash place 0 $sash0 [lindex $s0 1]
902 }
903 set oldwidth($win) $w
904}
905
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000906proc allcanvs args {
907 global canv canv2 canv3
908 eval $canv $args
909 eval $canv2 $args
910 eval $canv3 $args
911}
912
913proc bindall {event action} {
914 global canv canv2 canv3
915 bind $canv $event $action
916 bind $canv2 $event $action
917 bind $canv3 $event $action
918}
919
Paul Mackerras9a40c502005-05-12 23:46:16 +0000920proc about {} {
921 set w .about
922 if {[winfo exists $w]} {
923 raise $w
924 return
925 }
926 toplevel $w
927 wm title $w "About gitk"
928 message $w.m -text {
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100929Gitk - a commit viewer for git
Paul Mackerras9a40c502005-05-12 23:46:16 +0000930
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100931Copyright © 2005-2006 Paul Mackerras
Paul Mackerras9a40c502005-05-12 23:46:16 +0000932
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000933Use and redistribute under the terms of the GNU General Public License} \
Paul Mackerras9a40c502005-05-12 23:46:16 +0000934 -justify center -aspect 400
935 pack $w.m -side top -fill x -padx 20 -pady 20
936 button $w.ok -text Close -command "destroy $w"
937 pack $w.ok -side bottom
938}
939
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000940proc keys {} {
941 set w .keys
942 if {[winfo exists $w]} {
943 raise $w
944 return
945 }
946 toplevel $w
947 wm title $w "Gitk key bindings"
948 message $w.m -text {
949Gitk key bindings:
950
951<Ctrl-Q> Quit
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000952<Home> Move to first commit
953<End> Move to last commit
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000954<Up>, p, i Move up one commit
955<Down>, n, k Move down one commit
956<Left>, z, j Go back in history list
957<Right>, x, l Go forward in history list
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000958<PageUp> Move up one page in commit list
959<PageDown> Move down one page in commit list
960<Ctrl-Home> Scroll to top of commit list
961<Ctrl-End> Scroll to bottom of commit list
962<Ctrl-Up> Scroll commit list up one line
963<Ctrl-Down> Scroll commit list down one line
964<Ctrl-PageUp> Scroll commit list up one page
965<Ctrl-PageDown> Scroll commit list down one page
Paul Mackerras4e7d6772006-05-30 21:33:07 +1000966<Shift-Up> Move to previous highlighted line
967<Shift-Down> Move to next highlighted line
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000968<Delete>, b Scroll diff view up one page
969<Backspace> Scroll diff view up one page
970<Space> Scroll diff view down one page
971u Scroll diff view up 18 lines
972d Scroll diff view down 18 lines
973<Ctrl-F> Find
974<Ctrl-G> Move to next find hit
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000975<Return> Move to next find hit
976/ Move to next find hit, or redo find
977? Move to previous find hit
978f Scroll diff view to next file
Paul Mackerras4e7d6772006-05-30 21:33:07 +1000979<Ctrl-S> Search for next hit in diff view
980<Ctrl-R> Search for previous hit in diff view
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000981<Ctrl-KP+> Increase font size
982<Ctrl-plus> Increase font size
983<Ctrl-KP-> Decrease font size
984<Ctrl-minus> Decrease font size
985} \
986 -justify left -bg white -border 2 -relief sunken
987 pack $w.m -side top -fill both
988 button $w.ok -text Close -command "destroy $w"
989 pack $w.ok -side bottom
990}
991
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000992# Procedures for manipulating the file list window at the
993# bottom right of the overall window.
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000994
995proc treeview {w l openlevs} {
996 global treecontents treediropen treeheight treeparent treeindex
997
998 set ix 0
999 set treeindex() 0
1000 set lev 0
1001 set prefix {}
1002 set prefixend -1
1003 set prefendstack {}
1004 set htstack {}
1005 set ht 0
1006 set treecontents() {}
1007 $w conf -state normal
1008 foreach f $l {
1009 while {[string range $f 0 $prefixend] ne $prefix} {
1010 if {$lev <= $openlevs} {
1011 $w mark set e:$treeindex($prefix) "end -1c"
1012 $w mark gravity e:$treeindex($prefix) left
1013 }
1014 set treeheight($prefix) $ht
1015 incr ht [lindex $htstack end]
1016 set htstack [lreplace $htstack end end]
1017 set prefixend [lindex $prefendstack end]
1018 set prefendstack [lreplace $prefendstack end end]
1019 set prefix [string range $prefix 0 $prefixend]
1020 incr lev -1
1021 }
1022 set tail [string range $f [expr {$prefixend+1}] end]
1023 while {[set slash [string first "/" $tail]] >= 0} {
1024 lappend htstack $ht
1025 set ht 0
1026 lappend prefendstack $prefixend
1027 incr prefixend [expr {$slash + 1}]
1028 set d [string range $tail 0 $slash]
1029 lappend treecontents($prefix) $d
1030 set oldprefix $prefix
1031 append prefix $d
1032 set treecontents($prefix) {}
1033 set treeindex($prefix) [incr ix]
1034 set treeparent($prefix) $oldprefix
1035 set tail [string range $tail [expr {$slash+1}] end]
1036 if {$lev <= $openlevs} {
1037 set ht 1
1038 set treediropen($prefix) [expr {$lev < $openlevs}]
1039 set bm [expr {$lev == $openlevs? "tri-rt": "tri-dn"}]
1040 $w mark set d:$ix "end -1c"
1041 $w mark gravity d:$ix left
1042 set str "\n"
1043 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
1044 $w insert end $str
1045 $w image create end -align center -image $bm -padx 1 \
1046 -name a:$ix
Paul Mackerras45a9d502006-05-20 22:56:27 +10001047 $w insert end $d [highlight_tag $prefix]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001048 $w mark set s:$ix "end -1c"
1049 $w mark gravity s:$ix left
1050 }
1051 incr lev
1052 }
1053 if {$tail ne {}} {
1054 if {$lev <= $openlevs} {
1055 incr ht
1056 set str "\n"
1057 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
1058 $w insert end $str
Paul Mackerras45a9d502006-05-20 22:56:27 +10001059 $w insert end $tail [highlight_tag $f]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001060 }
1061 lappend treecontents($prefix) $tail
1062 }
1063 }
1064 while {$htstack ne {}} {
1065 set treeheight($prefix) $ht
1066 incr ht [lindex $htstack end]
1067 set htstack [lreplace $htstack end end]
1068 }
1069 $w conf -state disabled
1070}
1071
1072proc linetoelt {l} {
1073 global treeheight treecontents
1074
1075 set y 2
1076 set prefix {}
1077 while {1} {
1078 foreach e $treecontents($prefix) {
1079 if {$y == $l} {
1080 return "$prefix$e"
1081 }
1082 set n 1
1083 if {[string index $e end] eq "/"} {
1084 set n $treeheight($prefix$e)
1085 if {$y + $n > $l} {
1086 append prefix $e
1087 incr y
1088 break
1089 }
1090 }
1091 incr y $n
1092 }
1093 }
1094}
1095
Paul Mackerras45a9d502006-05-20 22:56:27 +10001096proc highlight_tree {y prefix} {
1097 global treeheight treecontents cflist
1098
1099 foreach e $treecontents($prefix) {
1100 set path $prefix$e
1101 if {[highlight_tag $path] ne {}} {
1102 $cflist tag add bold $y.0 "$y.0 lineend"
1103 }
1104 incr y
1105 if {[string index $e end] eq "/" && $treeheight($path) > 1} {
1106 set y [highlight_tree $y $path]
1107 }
1108 }
1109 return $y
1110}
1111
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001112proc treeclosedir {w dir} {
1113 global treediropen treeheight treeparent treeindex
1114
1115 set ix $treeindex($dir)
1116 $w conf -state normal
1117 $w delete s:$ix e:$ix
1118 set treediropen($dir) 0
1119 $w image configure a:$ix -image tri-rt
1120 $w conf -state disabled
1121 set n [expr {1 - $treeheight($dir)}]
1122 while {$dir ne {}} {
1123 incr treeheight($dir) $n
1124 set dir $treeparent($dir)
1125 }
1126}
1127
1128proc treeopendir {w dir} {
1129 global treediropen treeheight treeparent treecontents treeindex
1130
1131 set ix $treeindex($dir)
1132 $w conf -state normal
1133 $w image configure a:$ix -image tri-dn
1134 $w mark set e:$ix s:$ix
1135 $w mark gravity e:$ix right
1136 set lev 0
1137 set str "\n"
1138 set n [llength $treecontents($dir)]
1139 for {set x $dir} {$x ne {}} {set x $treeparent($x)} {
1140 incr lev
1141 append str "\t"
1142 incr treeheight($x) $n
1143 }
1144 foreach e $treecontents($dir) {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001145 set de $dir$e
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001146 if {[string index $e end] eq "/"} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001147 set iy $treeindex($de)
1148 $w mark set d:$iy e:$ix
1149 $w mark gravity d:$iy left
1150 $w insert e:$ix $str
1151 set treediropen($de) 0
1152 $w image create e:$ix -align center -image tri-rt -padx 1 \
1153 -name a:$iy
Paul Mackerras45a9d502006-05-20 22:56:27 +10001154 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001155 $w mark set s:$iy e:$ix
1156 $w mark gravity s:$iy left
1157 set treeheight($de) 1
1158 } else {
1159 $w insert e:$ix $str
Paul Mackerras45a9d502006-05-20 22:56:27 +10001160 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001161 }
1162 }
1163 $w mark gravity e:$ix left
1164 $w conf -state disabled
1165 set treediropen($dir) 1
1166 set top [lindex [split [$w index @0,0] .] 0]
1167 set ht [$w cget -height]
1168 set l [lindex [split [$w index s:$ix] .] 0]
1169 if {$l < $top} {
1170 $w yview $l.0
1171 } elseif {$l + $n + 1 > $top + $ht} {
1172 set top [expr {$l + $n + 2 - $ht}]
1173 if {$l < $top} {
1174 set top $l
1175 }
1176 $w yview $top.0
1177 }
1178}
1179
1180proc treeclick {w x y} {
1181 global treediropen cmitmode ctext cflist cflist_top
1182
1183 if {$cmitmode ne "tree"} return
1184 if {![info exists cflist_top]} return
1185 set l [lindex [split [$w index "@$x,$y"] "."] 0]
1186 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
1187 $cflist tag add highlight $l.0 "$l.0 lineend"
1188 set cflist_top $l
1189 if {$l == 1} {
1190 $ctext yview 1.0
1191 return
1192 }
1193 set e [linetoelt $l]
1194 if {[string index $e end] ne "/"} {
1195 showfile $e
1196 } elseif {$treediropen($e)} {
1197 treeclosedir $w $e
1198 } else {
1199 treeopendir $w $e
1200 }
1201}
1202
1203proc setfilelist {id} {
1204 global treefilelist cflist
1205
1206 treeview $cflist $treefilelist($id) 0
1207}
1208
1209image create bitmap tri-rt -background black -foreground blue -data {
1210 #define tri-rt_width 13
1211 #define tri-rt_height 13
1212 static unsigned char tri-rt_bits[] = {
1213 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x70, 0x00, 0xf0, 0x00,
1214 0xf0, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x30, 0x00, 0x10, 0x00, 0x00, 0x00,
1215 0x00, 0x00};
1216} -maskdata {
1217 #define tri-rt-mask_width 13
1218 #define tri-rt-mask_height 13
1219 static unsigned char tri-rt-mask_bits[] = {
1220 0x08, 0x00, 0x18, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf8, 0x00, 0xf8, 0x01,
1221 0xf8, 0x03, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0x38, 0x00, 0x18, 0x00,
1222 0x08, 0x00};
1223}
1224image create bitmap tri-dn -background black -foreground blue -data {
1225 #define tri-dn_width 13
1226 #define tri-dn_height 13
1227 static unsigned char tri-dn_bits[] = {
1228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xf8, 0x03,
1229 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1230 0x00, 0x00};
1231} -maskdata {
1232 #define tri-dn-mask_width 13
1233 #define tri-dn-mask_height 13
1234 static unsigned char tri-dn-mask_bits[] = {
1235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xfe, 0x0f, 0xfc, 0x07,
1236 0xf8, 0x03, 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
1237 0x00, 0x00};
1238}
1239
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001240proc init_flist {first} {
Paul Mackerras89b11d32006-05-02 19:55:31 +10001241 global cflist cflist_top selectedline difffilestart
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001242
1243 $cflist conf -state normal
1244 $cflist delete 0.0 end
1245 if {$first ne {}} {
1246 $cflist insert end $first
1247 set cflist_top 1
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001248 $cflist tag add highlight 1.0 "1.0 lineend"
1249 } else {
1250 catch {unset cflist_top}
1251 }
1252 $cflist conf -state disabled
1253 set difffilestart {}
1254}
1255
Paul Mackerras63b79192006-05-20 21:31:52 +10001256proc highlight_tag {f} {
1257 global highlight_paths
1258
1259 foreach p $highlight_paths {
1260 if {[string match $p $f]} {
1261 return "bold"
1262 }
1263 }
1264 return {}
1265}
1266
1267proc highlight_filelist {} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001268 global cmitmode cflist
Paul Mackerras63b79192006-05-20 21:31:52 +10001269
Paul Mackerras45a9d502006-05-20 22:56:27 +10001270 $cflist conf -state normal
1271 if {$cmitmode ne "tree"} {
Paul Mackerras63b79192006-05-20 21:31:52 +10001272 set end [lindex [split [$cflist index end] .] 0]
1273 for {set l 2} {$l < $end} {incr l} {
1274 set line [$cflist get $l.0 "$l.0 lineend"]
1275 if {[highlight_tag $line] ne {}} {
1276 $cflist tag add bold $l.0 "$l.0 lineend"
1277 }
1278 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10001279 } else {
1280 highlight_tree 2 {}
Paul Mackerras63b79192006-05-20 21:31:52 +10001281 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10001282 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 21:31:52 +10001283}
1284
1285proc unhighlight_filelist {} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001286 global cflist
Paul Mackerras63b79192006-05-20 21:31:52 +10001287
Paul Mackerras45a9d502006-05-20 22:56:27 +10001288 $cflist conf -state normal
1289 $cflist tag remove bold 1.0 end
1290 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 21:31:52 +10001291}
1292
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001293proc add_flist {fl} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001294 global cflist
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001295
Paul Mackerras45a9d502006-05-20 22:56:27 +10001296 $cflist conf -state normal
1297 foreach f $fl {
1298 $cflist insert end "\n"
1299 $cflist insert end $f [highlight_tag $f]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001300 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10001301 $cflist conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001302}
1303
1304proc sel_flist {w x y} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001305 global ctext difffilestart cflist cflist_top cmitmode
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001306
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001307 if {$cmitmode eq "tree"} return
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001308 if {![info exists cflist_top]} return
1309 set l [lindex [split [$w index "@$x,$y"] "."] 0]
Paul Mackerras89b11d32006-05-02 19:55:31 +10001310 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
1311 $cflist tag add highlight $l.0 "$l.0 lineend"
1312 set cflist_top $l
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001313 if {$l == 1} {
1314 $ctext yview 1.0
1315 } else {
1316 catch {$ctext yview [lindex $difffilestart [expr {$l - 2}]]}
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001317 }
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001318}
1319
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001320# Functions for adding and removing shell-type quoting
1321
1322proc shellquote {str} {
1323 if {![string match "*\['\"\\ \t]*" $str]} {
1324 return $str
1325 }
1326 if {![string match "*\['\"\\]*" $str]} {
1327 return "\"$str\""
1328 }
1329 if {![string match "*'*" $str]} {
1330 return "'$str'"
1331 }
1332 return "\"[string map {\" \\\" \\ \\\\} $str]\""
1333}
1334
1335proc shellarglist {l} {
1336 set str {}
1337 foreach a $l {
1338 if {$str ne {}} {
1339 append str " "
1340 }
1341 append str [shellquote $a]
1342 }
1343 return $str
1344}
1345
1346proc shelldequote {str} {
1347 set ret {}
1348 set used -1
1349 while {1} {
1350 incr used
1351 if {![regexp -start $used -indices "\['\"\\\\ \t]" $str first]} {
1352 append ret [string range $str $used end]
1353 set used [string length $str]
1354 break
1355 }
1356 set first [lindex $first 0]
1357 set ch [string index $str $first]
1358 if {$first > $used} {
1359 append ret [string range $str $used [expr {$first - 1}]]
1360 set used $first
1361 }
1362 if {$ch eq " " || $ch eq "\t"} break
1363 incr used
1364 if {$ch eq "'"} {
1365 set first [string first "'" $str $used]
1366 if {$first < 0} {
1367 error "unmatched single-quote"
1368 }
1369 append ret [string range $str $used [expr {$first - 1}]]
1370 set used $first
1371 continue
1372 }
1373 if {$ch eq "\\"} {
1374 if {$used >= [string length $str]} {
1375 error "trailing backslash"
1376 }
1377 append ret [string index $str $used]
1378 continue
1379 }
1380 # here ch == "\""
1381 while {1} {
1382 if {![regexp -start $used -indices "\[\"\\\\]" $str first]} {
1383 error "unmatched double-quote"
1384 }
1385 set first [lindex $first 0]
1386 set ch [string index $str $first]
1387 if {$first > $used} {
1388 append ret [string range $str $used [expr {$first - 1}]]
1389 set used $first
1390 }
1391 if {$ch eq "\""} break
1392 incr used
1393 append ret [string index $str $used]
1394 incr used
1395 }
1396 }
1397 return [list $used $ret]
1398}
1399
1400proc shellsplit {str} {
1401 set l {}
1402 while {1} {
1403 set str [string trimleft $str]
1404 if {$str eq {}} break
1405 set dq [shelldequote $str]
1406 set n [lindex $dq 0]
1407 set word [lindex $dq 1]
1408 set str [string range $str $n end]
1409 lappend l $word
1410 }
1411 return $l
1412}
1413
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001414# Code to implement multiple views
1415
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001416proc newview {ishighlight} {
1417 global nextviewnum newviewname newviewperm uifont newishighlight
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001418 global newviewargs revtreeargs
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001419
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001420 set newishighlight $ishighlight
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001421 set top .gitkview
1422 if {[winfo exists $top]} {
1423 raise $top
1424 return
1425 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001426 set newviewname($nextviewnum) "View $nextviewnum"
1427 set newviewperm($nextviewnum) 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001428 set newviewargs($nextviewnum) [shellarglist $revtreeargs]
Mark Levedahl40b87ff2007-02-01 08:44:46 -05001429 vieweditor $top $nextviewnum "Gitk view definition"
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001430}
1431
1432proc editview {} {
1433 global curview
1434 global viewname viewperm newviewname newviewperm
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001435 global viewargs newviewargs
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001436
1437 set top .gitkvedit-$curview
1438 if {[winfo exists $top]} {
1439 raise $top
1440 return
1441 }
1442 set newviewname($curview) $viewname($curview)
1443 set newviewperm($curview) $viewperm($curview)
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001444 set newviewargs($curview) [shellarglist $viewargs($curview)]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001445 vieweditor $top $curview "Gitk: edit view $viewname($curview)"
1446}
1447
1448proc vieweditor {top n title} {
1449 global newviewname newviewperm viewfiles
1450 global uifont
1451
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001452 toplevel $top
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001453 wm title $top $title
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001454 label $top.nl -text "Name" -font $uifont
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001455 entry $top.name -width 20 -textvariable newviewname($n)
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001456 grid $top.nl $top.name -sticky w -pady 5
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001457 checkbutton $top.perm -text "Remember this view" -variable newviewperm($n)
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001458 grid $top.perm - -pady 5 -sticky w
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001459 message $top.al -aspect 1000 -font $uifont \
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03001460 -text "Commits to include (arguments to git rev-list):"
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001461 grid $top.al - -sticky w -pady 5
1462 entry $top.args -width 50 -textvariable newviewargs($n) \
1463 -background white
1464 grid $top.args - -sticky ew -padx 5
1465 message $top.l -aspect 1000 -font $uifont \
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001466 -text "Enter files and directories to include, one per line:"
1467 grid $top.l - -sticky w
1468 text $top.t -width 40 -height 10 -background white
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001469 if {[info exists viewfiles($n)]} {
1470 foreach f $viewfiles($n) {
1471 $top.t insert end $f
1472 $top.t insert end "\n"
1473 }
1474 $top.t delete {end - 1c} end
1475 $top.t mark set insert 0.0
1476 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001477 grid $top.t - -sticky ew -padx 5
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001478 frame $top.buts
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001479 button $top.buts.ok -text "OK" -command [list newviewok $top $n]
1480 button $top.buts.can -text "Cancel" -command [list destroy $top]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001481 grid $top.buts.ok $top.buts.can
1482 grid columnconfigure $top.buts 0 -weight 1 -uniform a
1483 grid columnconfigure $top.buts 1 -weight 1 -uniform a
1484 grid $top.buts - -pady 10 -sticky ew
1485 focus $top.t
1486}
1487
Paul Mackerras908c3582006-05-20 09:38:11 +10001488proc doviewmenu {m first cmd op argv} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001489 set nmenu [$m index end]
1490 for {set i $first} {$i <= $nmenu} {incr i} {
1491 if {[$m entrycget $i -command] eq $cmd} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001492 eval $m $op $i $argv
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001493 break
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001494 }
1495 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001496}
1497
1498proc allviewmenus {n op args} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001499 global viewhlmenu
1500
Paul Mackerras3cd204e2006-11-23 21:06:16 +11001501 doviewmenu .bar.view 5 [list showview $n] $op $args
Paul Mackerras908c3582006-05-20 09:38:11 +10001502 doviewmenu $viewhlmenu 1 [list addvhighlight $n] $op $args
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001503}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001504
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001505proc newviewok {top n} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001506 global nextviewnum newviewperm newviewname newishighlight
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001507 global viewname viewfiles viewperm selectedview curview
Paul Mackerras908c3582006-05-20 09:38:11 +10001508 global viewargs newviewargs viewhlmenu
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001509
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001510 if {[catch {
1511 set newargs [shellsplit $newviewargs($n)]
1512 } err]} {
1513 error_popup "Error in commit selection arguments: $err"
1514 wm raise $top
1515 focus $top
1516 return
1517 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001518 set files {}
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001519 foreach f [split [$top.t get 0.0 end] "\n"] {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001520 set ft [string trim $f]
1521 if {$ft ne {}} {
1522 lappend files $ft
1523 }
1524 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001525 if {![info exists viewfiles($n)]} {
1526 # creating a new view
1527 incr nextviewnum
1528 set viewname($n) $newviewname($n)
1529 set viewperm($n) $newviewperm($n)
1530 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001531 set viewargs($n) $newargs
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001532 addviewmenu $n
1533 if {!$newishighlight} {
1534 after idle showview $n
1535 } else {
Paul Mackerras908c3582006-05-20 09:38:11 +10001536 after idle addvhighlight $n
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001537 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001538 } else {
1539 # editing an existing view
1540 set viewperm($n) $newviewperm($n)
1541 if {$newviewname($n) ne $viewname($n)} {
1542 set viewname($n) $newviewname($n)
Paul Mackerras3cd204e2006-11-23 21:06:16 +11001543 doviewmenu .bar.view 5 [list showview $n] \
Paul Mackerras908c3582006-05-20 09:38:11 +10001544 entryconf [list -label $viewname($n)]
1545 doviewmenu $viewhlmenu 1 [list addvhighlight $n] \
1546 entryconf [list -label $viewname($n) -value $viewname($n)]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001547 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001548 if {$files ne $viewfiles($n) || $newargs ne $viewargs($n)} {
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001549 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001550 set viewargs($n) $newargs
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001551 if {$curview == $n} {
1552 after idle updatecommits
1553 }
1554 }
1555 }
1556 catch {destroy $top}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001557}
1558
1559proc delview {} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001560 global curview viewdata viewperm hlview selectedhlview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001561
1562 if {$curview == 0} return
Paul Mackerras908c3582006-05-20 09:38:11 +10001563 if {[info exists hlview] && $hlview == $curview} {
1564 set selectedhlview None
1565 unset hlview
1566 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001567 allviewmenus $curview delete
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001568 set viewdata($curview) {}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001569 set viewperm($curview) 0
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001570 showview 0
1571}
1572
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001573proc addviewmenu {n} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001574 global viewname viewhlmenu
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001575
1576 .bar.view add radiobutton -label $viewname($n) \
1577 -command [list showview $n] -variable selectedview -value $n
Paul Mackerras908c3582006-05-20 09:38:11 +10001578 $viewhlmenu add radiobutton -label $viewname($n) \
1579 -command [list addvhighlight $n] -variable selectedhlview
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001580}
1581
Paul Mackerras22626ef2006-04-17 09:56:02 +10001582proc flatten {var} {
1583 global $var
1584
1585 set ret {}
1586 foreach i [array names $var] {
1587 lappend ret $i [set $var\($i\)]
1588 }
1589 return $ret
1590}
1591
1592proc unflatten {var l} {
1593 global $var
1594
1595 catch {unset $var}
1596 foreach {i v} $l {
1597 set $var\($i\) $v
1598 }
1599}
1600
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001601proc showview {n} {
1602 global curview viewdata viewfiles
1603 global displayorder parentlist childlist rowidlist rowoffsets
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001604 global colormap rowtextx commitrow nextcolor canvxmax
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001605 global numcommits rowrangelist commitlisted idrowranges
1606 global selectedline currentid canv canvy0
1607 global matchinglines treediffs
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10001608 global pending_select phase
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001609 global commitidx rowlaidout rowoptim linesegends
Paul Mackerras22626ef2006-04-17 09:56:02 +10001610 global commfd nextupdate
Paul Mackerras908c3582006-05-20 09:38:11 +10001611 global selectedview
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001612 global vparentlist vchildlist vdisporder vcmitlisted
Paul Mackerras908c3582006-05-20 09:38:11 +10001613 global hlview selectedhlview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001614
1615 if {$n == $curview} return
1616 set selid {}
1617 if {[info exists selectedline]} {
1618 set selid $currentid
1619 set y [yc $selectedline]
1620 set ymax [lindex [$canv cget -scrollregion] 3]
1621 set span [$canv yview]
1622 set ytop [expr {[lindex $span 0] * $ymax}]
1623 set ybot [expr {[lindex $span 1] * $ymax}]
1624 if {$ytop < $y && $y < $ybot} {
1625 set yscreen [expr {$y - $ytop}]
1626 } else {
1627 set yscreen [expr {($ybot - $ytop) / 2}]
1628 }
1629 }
1630 unselectline
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10001631 normalline
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001632 stopfindproc
Paul Mackerras22626ef2006-04-17 09:56:02 +10001633 if {$curview >= 0} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001634 set vparentlist($curview) $parentlist
1635 set vchildlist($curview) $childlist
1636 set vdisporder($curview) $displayorder
1637 set vcmitlisted($curview) $commitlisted
Paul Mackerras22626ef2006-04-17 09:56:02 +10001638 if {$phase ne {}} {
1639 set viewdata($curview) \
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001640 [list $phase $rowidlist $rowoffsets $rowrangelist \
1641 [flatten idrowranges] [flatten idinlist] \
1642 $rowlaidout $rowoptim $numcommits $linesegends]
Paul Mackerras2516dae2006-04-21 10:35:31 +10001643 } elseif {![info exists viewdata($curview)]
1644 || [lindex $viewdata($curview) 0] ne {}} {
Paul Mackerras22626ef2006-04-17 09:56:02 +10001645 set viewdata($curview) \
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001646 [list {} $rowidlist $rowoffsets $rowrangelist]
Paul Mackerras22626ef2006-04-17 09:56:02 +10001647 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001648 }
1649 catch {unset matchinglines}
1650 catch {unset treediffs}
1651 clear_display
Paul Mackerras908c3582006-05-20 09:38:11 +10001652 if {[info exists hlview] && $hlview == $n} {
1653 unset hlview
1654 set selectedhlview None
1655 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001656
1657 set curview $n
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001658 set selectedview $n
Paul Mackerras3cd204e2006-11-23 21:06:16 +11001659 .bar.view entryconf Edit* -state [expr {$n == 0? "disabled": "normal"}]
1660 .bar.view entryconf Delete* -state [expr {$n == 0? "disabled": "normal"}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001661
1662 if {![info exists viewdata($n)]} {
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10001663 set pending_select $selid
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10001664 getcommits
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001665 return
1666 }
1667
Paul Mackerras22626ef2006-04-17 09:56:02 +10001668 set v $viewdata($n)
1669 set phase [lindex $v 0]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001670 set displayorder $vdisporder($n)
1671 set parentlist $vparentlist($n)
1672 set childlist $vchildlist($n)
1673 set commitlisted $vcmitlisted($n)
1674 set rowidlist [lindex $v 1]
1675 set rowoffsets [lindex $v 2]
1676 set rowrangelist [lindex $v 3]
Paul Mackerras22626ef2006-04-17 09:56:02 +10001677 if {$phase eq {}} {
1678 set numcommits [llength $displayorder]
1679 catch {unset idrowranges}
Paul Mackerras22626ef2006-04-17 09:56:02 +10001680 } else {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001681 unflatten idrowranges [lindex $v 4]
1682 unflatten idinlist [lindex $v 5]
1683 set rowlaidout [lindex $v 6]
1684 set rowoptim [lindex $v 7]
1685 set numcommits [lindex $v 8]
1686 set linesegends [lindex $v 9]
Paul Mackerras22626ef2006-04-17 09:56:02 +10001687 }
1688
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001689 catch {unset colormap}
1690 catch {unset rowtextx}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001691 set nextcolor 0
1692 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001693 set curview $n
1694 set row 0
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001695 setcanvscroll
1696 set yf 0
1697 set row 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001698 if {$selid ne {} && [info exists commitrow($n,$selid)]} {
1699 set row $commitrow($n,$selid)
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001700 # try to get the selected row in the same position on the screen
1701 set ymax [lindex [$canv cget -scrollregion] 3]
1702 set ytop [expr {[yc $row] - $yscreen}]
1703 if {$ytop < 0} {
1704 set ytop 0
1705 }
1706 set yf [expr {$ytop * 1.0 / $ymax}]
1707 }
1708 allcanvs yview moveto $yf
1709 drawvisible
1710 selectline $row 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001711 if {$phase ne {}} {
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001712 if {$phase eq "getcommits"} {
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001713 show_status "Reading commits..."
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001714 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001715 if {[info exists commfd($n)]} {
Paul Mackerrasd1e46752006-08-16 20:02:32 +10001716 layoutmore {}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001717 } else {
1718 finishcommits
1719 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001720 } elseif {$numcommits == 0} {
1721 show_status "No commits selected"
Paul Mackerras2516dae2006-04-21 10:35:31 +10001722 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001723}
1724
Paul Mackerras908c3582006-05-20 09:38:11 +10001725# Stuff relating to the highlighting facility
1726
1727proc ishighlighted {row} {
Paul Mackerras164ff272006-05-29 19:50:02 +10001728 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras908c3582006-05-20 09:38:11 +10001729
1730 if {[info exists nhighlights($row)] && $nhighlights($row) > 0} {
1731 return $nhighlights($row)
1732 }
1733 if {[info exists vhighlights($row)] && $vhighlights($row) > 0} {
1734 return $vhighlights($row)
1735 }
1736 if {[info exists fhighlights($row)] && $fhighlights($row) > 0} {
1737 return $fhighlights($row)
1738 }
Paul Mackerras164ff272006-05-29 19:50:02 +10001739 if {[info exists rhighlights($row)] && $rhighlights($row) > 0} {
1740 return $rhighlights($row)
1741 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001742 return 0
1743}
1744
1745proc bolden {row font} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001746 global canv linehtag selectedline boldrows
Paul Mackerras908c3582006-05-20 09:38:11 +10001747
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001748 lappend boldrows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10001749 $canv itemconf $linehtag($row) -font $font
Paul Mackerras5864c082006-05-26 22:22:48 +10001750 if {[info exists selectedline] && $row == $selectedline} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001751 $canv delete secsel
1752 set t [eval $canv create rect [$canv bbox $linehtag($row)] \
1753 -outline {{}} -tags secsel \
1754 -fill [$canv cget -selectbackground]]
1755 $canv lower $t
1756 }
1757}
1758
1759proc bolden_name {row font} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001760 global canv2 linentag selectedline boldnamerows
Paul Mackerras908c3582006-05-20 09:38:11 +10001761
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001762 lappend boldnamerows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10001763 $canv2 itemconf $linentag($row) -font $font
Paul Mackerras5864c082006-05-26 22:22:48 +10001764 if {[info exists selectedline] && $row == $selectedline} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001765 $canv2 delete secsel
1766 set t [eval $canv2 create rect [$canv2 bbox $linentag($row)] \
1767 -outline {{}} -tags secsel \
1768 -fill [$canv2 cget -selectbackground]]
1769 $canv2 lower $t
1770 }
1771}
1772
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001773proc unbolden {} {
1774 global mainfont boldrows
Paul Mackerras908c3582006-05-20 09:38:11 +10001775
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001776 set stillbold {}
1777 foreach row $boldrows {
Paul Mackerras908c3582006-05-20 09:38:11 +10001778 if {![ishighlighted $row]} {
1779 bolden $row $mainfont
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001780 } else {
1781 lappend stillbold $row
Paul Mackerras908c3582006-05-20 09:38:11 +10001782 }
1783 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001784 set boldrows $stillbold
Paul Mackerras908c3582006-05-20 09:38:11 +10001785}
1786
1787proc addvhighlight {n} {
1788 global hlview curview viewdata vhl_done vhighlights commitidx
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001789
1790 if {[info exists hlview]} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001791 delvhighlight
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001792 }
1793 set hlview $n
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001794 if {$n != $curview && ![info exists viewdata($n)]} {
1795 set viewdata($n) [list getcommits {{}} {{}} {} {} {} 0 0 0 {}]
1796 set vparentlist($n) {}
1797 set vchildlist($n) {}
1798 set vdisporder($n) {}
1799 set vcmitlisted($n) {}
1800 start_rev_list $n
Paul Mackerras908c3582006-05-20 09:38:11 +10001801 }
1802 set vhl_done $commitidx($hlview)
1803 if {$vhl_done > 0} {
1804 drawvisible
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001805 }
1806}
1807
Paul Mackerras908c3582006-05-20 09:38:11 +10001808proc delvhighlight {} {
1809 global hlview vhighlights
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001810
1811 if {![info exists hlview]} return
1812 unset hlview
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001813 catch {unset vhighlights}
1814 unbolden
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001815}
1816
Paul Mackerras908c3582006-05-20 09:38:11 +10001817proc vhighlightmore {} {
1818 global hlview vhl_done commitidx vhighlights
1819 global displayorder vdisporder curview mainfont
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001820
1821 set font [concat $mainfont bold]
1822 set max $commitidx($hlview)
1823 if {$hlview == $curview} {
1824 set disp $displayorder
1825 } else {
1826 set disp $vdisporder($hlview)
1827 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001828 set vr [visiblerows]
1829 set r0 [lindex $vr 0]
1830 set r1 [lindex $vr 1]
1831 for {set i $vhl_done} {$i < $max} {incr i} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001832 set id [lindex $disp $i]
1833 if {[info exists commitrow($curview,$id)]} {
1834 set row $commitrow($curview,$id)
Paul Mackerras908c3582006-05-20 09:38:11 +10001835 if {$r0 <= $row && $row <= $r1} {
1836 if {![highlighted $row]} {
1837 bolden $row $font
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001838 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001839 set vhighlights($row) 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001840 }
1841 }
1842 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001843 set vhl_done $max
1844}
1845
1846proc askvhighlight {row id} {
1847 global hlview vhighlights commitrow iddrawn mainfont
1848
1849 if {[info exists commitrow($hlview,$id)]} {
1850 if {[info exists iddrawn($id)] && ![ishighlighted $row]} {
1851 bolden $row [concat $mainfont bold]
1852 }
1853 set vhighlights($row) 1
1854 } else {
1855 set vhighlights($row) 0
1856 }
1857}
1858
1859proc hfiles_change {name ix op} {
1860 global highlight_files filehighlight fhighlights fh_serial
Paul Mackerras63b79192006-05-20 21:31:52 +10001861 global mainfont highlight_paths
Paul Mackerras908c3582006-05-20 09:38:11 +10001862
1863 if {[info exists filehighlight]} {
1864 # delete previous highlights
1865 catch {close $filehighlight}
1866 unset filehighlight
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001867 catch {unset fhighlights}
1868 unbolden
Paul Mackerras63b79192006-05-20 21:31:52 +10001869 unhighlight_filelist
Paul Mackerras908c3582006-05-20 09:38:11 +10001870 }
Paul Mackerras63b79192006-05-20 21:31:52 +10001871 set highlight_paths {}
Paul Mackerras908c3582006-05-20 09:38:11 +10001872 after cancel do_file_hl $fh_serial
1873 incr fh_serial
1874 if {$highlight_files ne {}} {
1875 after 300 do_file_hl $fh_serial
1876 }
1877}
1878
Paul Mackerras63b79192006-05-20 21:31:52 +10001879proc makepatterns {l} {
1880 set ret {}
1881 foreach e $l {
1882 set ee [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} $e]
1883 if {[string index $ee end] eq "/"} {
1884 lappend ret "$ee*"
1885 } else {
1886 lappend ret $ee
1887 lappend ret "$ee/*"
1888 }
1889 }
1890 return $ret
1891}
1892
Paul Mackerras908c3582006-05-20 09:38:11 +10001893proc do_file_hl {serial} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001894 global highlight_files filehighlight highlight_paths gdttype fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001895
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001896 if {$gdttype eq "touching paths:"} {
1897 if {[catch {set paths [shellsplit $highlight_files]}]} return
1898 set highlight_paths [makepatterns $paths]
1899 highlight_filelist
1900 set gdtargs [concat -- $paths]
1901 } else {
1902 set gdtargs [list "-S$highlight_files"]
1903 }
1904 set cmd [concat | git-diff-tree -r -s --stdin $gdtargs]
Paul Mackerras908c3582006-05-20 09:38:11 +10001905 set filehighlight [open $cmd r+]
1906 fconfigure $filehighlight -blocking 0
1907 fileevent $filehighlight readable readfhighlight
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001908 set fhl_list {}
Paul Mackerras908c3582006-05-20 09:38:11 +10001909 drawvisible
1910 flushhighlights
1911}
1912
1913proc flushhighlights {} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001914 global filehighlight fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001915
1916 if {[info exists filehighlight]} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001917 lappend fhl_list {}
Paul Mackerras908c3582006-05-20 09:38:11 +10001918 puts $filehighlight ""
1919 flush $filehighlight
1920 }
1921}
1922
1923proc askfilehighlight {row id} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001924 global filehighlight fhighlights fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001925
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001926 lappend fhl_list $id
1927 set fhighlights($row) -1
Paul Mackerras908c3582006-05-20 09:38:11 +10001928 puts $filehighlight $id
1929}
1930
1931proc readfhighlight {} {
1932 global filehighlight fhighlights commitrow curview mainfont iddrawn
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001933 global fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001934
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001935 while {[gets $filehighlight line] >= 0} {
1936 set line [string trim $line]
1937 set i [lsearch -exact $fhl_list $line]
1938 if {$i < 0} continue
1939 for {set j 0} {$j < $i} {incr j} {
1940 set id [lindex $fhl_list $j]
1941 if {[info exists commitrow($curview,$id)]} {
1942 set fhighlights($commitrow($curview,$id)) 0
1943 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001944 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001945 set fhl_list [lrange $fhl_list [expr {$i+1}] end]
1946 if {$line eq {}} continue
1947 if {![info exists commitrow($curview,$line)]} continue
1948 set row $commitrow($curview,$line)
1949 if {[info exists iddrawn($line)] && ![ishighlighted $row]} {
1950 bolden $row [concat $mainfont bold]
1951 }
1952 set fhighlights($row) 1
Paul Mackerras908c3582006-05-20 09:38:11 +10001953 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001954 if {[eof $filehighlight]} {
1955 # strange...
1956 puts "oops, git-diff-tree died"
1957 catch {close $filehighlight}
1958 unset filehighlight
Paul Mackerras908c3582006-05-20 09:38:11 +10001959 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001960 next_hlcont
Paul Mackerras908c3582006-05-20 09:38:11 +10001961}
1962
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001963proc find_change {name ix op} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001964 global nhighlights mainfont boldnamerows
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001965 global findstring findpattern findtype
Paul Mackerras908c3582006-05-20 09:38:11 +10001966
1967 # delete previous highlights, if any
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001968 foreach row $boldnamerows {
1969 bolden_name $row $mainfont
Paul Mackerras908c3582006-05-20 09:38:11 +10001970 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001971 set boldnamerows {}
1972 catch {unset nhighlights}
1973 unbolden
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001974 if {$findtype ne "Regexp"} {
1975 set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \
1976 $findstring]
1977 set findpattern "*$e*"
Paul Mackerras908c3582006-05-20 09:38:11 +10001978 }
1979 drawvisible
1980}
1981
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001982proc askfindhighlight {row id} {
1983 global nhighlights commitinfo iddrawn mainfont
1984 global findstring findtype findloc findpattern
Paul Mackerras908c3582006-05-20 09:38:11 +10001985
1986 if {![info exists commitinfo($id)]} {
1987 getcommit $id
1988 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001989 set info $commitinfo($id)
Paul Mackerras908c3582006-05-20 09:38:11 +10001990 set isbold 0
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001991 set fldtypes {Headline Author Date Committer CDate Comments}
1992 foreach f $info ty $fldtypes {
1993 if {$findloc ne "All fields" && $findloc ne $ty} {
1994 continue
Paul Mackerras908c3582006-05-20 09:38:11 +10001995 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001996 if {$findtype eq "Regexp"} {
1997 set doesmatch [regexp $findstring $f]
1998 } elseif {$findtype eq "IgnCase"} {
1999 set doesmatch [string match -nocase $findpattern $f]
2000 } else {
2001 set doesmatch [string match $findpattern $f]
2002 }
2003 if {$doesmatch} {
2004 if {$ty eq "Author"} {
2005 set isbold 2
2006 } else {
2007 set isbold 1
2008 }
Paul Mackerras908c3582006-05-20 09:38:11 +10002009 }
2010 }
2011 if {[info exists iddrawn($id)]} {
2012 if {$isbold && ![ishighlighted $row]} {
2013 bolden $row [concat $mainfont bold]
2014 }
2015 if {$isbold >= 2} {
2016 bolden_name $row [concat $mainfont bold]
2017 }
2018 }
2019 set nhighlights($row) $isbold
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002020}
2021
Paul Mackerras164ff272006-05-29 19:50:02 +10002022proc vrel_change {name ix op} {
2023 global highlight_related
2024
2025 rhighlight_none
2026 if {$highlight_related ne "None"} {
2027 after idle drawvisible
2028 }
2029}
2030
2031# prepare for testing whether commits are descendents or ancestors of a
2032proc rhighlight_sel {a} {
2033 global descendent desc_todo ancestor anc_todo
2034 global highlight_related rhighlights
2035
2036 catch {unset descendent}
2037 set desc_todo [list $a]
2038 catch {unset ancestor}
2039 set anc_todo [list $a]
2040 if {$highlight_related ne "None"} {
2041 rhighlight_none
2042 after idle drawvisible
2043 }
2044}
2045
2046proc rhighlight_none {} {
2047 global rhighlights
2048
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002049 catch {unset rhighlights}
2050 unbolden
Paul Mackerras164ff272006-05-29 19:50:02 +10002051}
2052
2053proc is_descendent {a} {
2054 global curview children commitrow descendent desc_todo
2055
2056 set v $curview
2057 set la $commitrow($v,$a)
2058 set todo $desc_todo
2059 set leftover {}
2060 set done 0
2061 for {set i 0} {$i < [llength $todo]} {incr i} {
2062 set do [lindex $todo $i]
2063 if {$commitrow($v,$do) < $la} {
2064 lappend leftover $do
2065 continue
2066 }
2067 foreach nk $children($v,$do) {
2068 if {![info exists descendent($nk)]} {
2069 set descendent($nk) 1
2070 lappend todo $nk
2071 if {$nk eq $a} {
2072 set done 1
2073 }
2074 }
2075 }
2076 if {$done} {
2077 set desc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
2078 return
2079 }
2080 }
2081 set descendent($a) 0
2082 set desc_todo $leftover
2083}
2084
2085proc is_ancestor {a} {
2086 global curview parentlist commitrow ancestor anc_todo
2087
2088 set v $curview
2089 set la $commitrow($v,$a)
2090 set todo $anc_todo
2091 set leftover {}
2092 set done 0
2093 for {set i 0} {$i < [llength $todo]} {incr i} {
2094 set do [lindex $todo $i]
2095 if {![info exists commitrow($v,$do)] || $commitrow($v,$do) > $la} {
2096 lappend leftover $do
2097 continue
2098 }
2099 foreach np [lindex $parentlist $commitrow($v,$do)] {
2100 if {![info exists ancestor($np)]} {
2101 set ancestor($np) 1
2102 lappend todo $np
2103 if {$np eq $a} {
2104 set done 1
2105 }
2106 }
2107 }
2108 if {$done} {
2109 set anc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
2110 return
2111 }
2112 }
2113 set ancestor($a) 0
2114 set anc_todo $leftover
2115}
2116
2117proc askrelhighlight {row id} {
2118 global descendent highlight_related iddrawn mainfont rhighlights
2119 global selectedline ancestor
2120
2121 if {![info exists selectedline]} return
2122 set isbold 0
2123 if {$highlight_related eq "Descendent" ||
2124 $highlight_related eq "Not descendent"} {
2125 if {![info exists descendent($id)]} {
2126 is_descendent $id
2127 }
2128 if {$descendent($id) == ($highlight_related eq "Descendent")} {
2129 set isbold 1
2130 }
2131 } elseif {$highlight_related eq "Ancestor" ||
2132 $highlight_related eq "Not ancestor"} {
2133 if {![info exists ancestor($id)]} {
2134 is_ancestor $id
2135 }
2136 if {$ancestor($id) == ($highlight_related eq "Ancestor")} {
2137 set isbold 1
2138 }
2139 }
2140 if {[info exists iddrawn($id)]} {
2141 if {$isbold && ![ishighlighted $row]} {
2142 bolden $row [concat $mainfont bold]
2143 }
2144 }
2145 set rhighlights($row) $isbold
2146}
2147
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002148proc next_hlcont {} {
2149 global fhl_row fhl_dirn displayorder numcommits
2150 global vhighlights fhighlights nhighlights rhighlights
2151 global hlview filehighlight findstring highlight_related
2152
2153 if {![info exists fhl_dirn] || $fhl_dirn == 0} return
2154 set row $fhl_row
2155 while {1} {
2156 if {$row < 0 || $row >= $numcommits} {
2157 bell
2158 set fhl_dirn 0
2159 return
2160 }
2161 set id [lindex $displayorder $row]
2162 if {[info exists hlview]} {
2163 if {![info exists vhighlights($row)]} {
2164 askvhighlight $row $id
2165 }
2166 if {$vhighlights($row) > 0} break
2167 }
2168 if {$findstring ne {}} {
2169 if {![info exists nhighlights($row)]} {
2170 askfindhighlight $row $id
2171 }
2172 if {$nhighlights($row) > 0} break
2173 }
2174 if {$highlight_related ne "None"} {
2175 if {![info exists rhighlights($row)]} {
2176 askrelhighlight $row $id
2177 }
2178 if {$rhighlights($row) > 0} break
2179 }
2180 if {[info exists filehighlight]} {
2181 if {![info exists fhighlights($row)]} {
2182 # ask for a few more while we're at it...
2183 set r $row
2184 for {set n 0} {$n < 100} {incr n} {
2185 if {![info exists fhighlights($r)]} {
2186 askfilehighlight $r [lindex $displayorder $r]
2187 }
2188 incr r $fhl_dirn
2189 if {$r < 0 || $r >= $numcommits} break
2190 }
2191 flushhighlights
2192 }
2193 if {$fhighlights($row) < 0} {
2194 set fhl_row $row
2195 return
2196 }
2197 if {$fhighlights($row) > 0} break
2198 }
2199 incr row $fhl_dirn
2200 }
2201 set fhl_dirn 0
2202 selectline $row 1
2203}
2204
2205proc next_highlight {dirn} {
2206 global selectedline fhl_row fhl_dirn
2207 global hlview filehighlight findstring highlight_related
2208
2209 if {![info exists selectedline]} return
2210 if {!([info exists hlview] || $findstring ne {} ||
2211 $highlight_related ne "None" || [info exists filehighlight])} return
2212 set fhl_row [expr {$selectedline + $dirn}]
2213 set fhl_dirn $dirn
2214 next_hlcont
2215}
2216
2217proc cancel_next_highlight {} {
2218 global fhl_dirn
2219
2220 set fhl_dirn 0
2221}
2222
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002223# Graph layout functions
2224
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002225proc shortids {ids} {
2226 set res {}
2227 foreach id $ids {
2228 if {[llength $id] > 1} {
2229 lappend res [shortids $id]
2230 } elseif {[regexp {^[0-9a-f]{40}$} $id]} {
2231 lappend res [string range $id 0 7]
2232 } else {
2233 lappend res $id
2234 }
2235 }
2236 return $res
2237}
2238
2239proc incrange {l x o} {
2240 set n [llength $l]
2241 while {$x < $n} {
2242 set e [lindex $l $x]
2243 if {$e ne {}} {
2244 lset l $x [expr {$e + $o}]
2245 }
2246 incr x
2247 }
2248 return $l
2249}
2250
2251proc ntimes {n o} {
2252 set ret {}
2253 for {} {$n > 0} {incr n -1} {
2254 lappend ret $o
2255 }
2256 return $ret
2257}
2258
2259proc usedinrange {id l1 l2} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002260 global children commitrow childlist curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002261
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002262 if {[info exists commitrow($curview,$id)]} {
2263 set r $commitrow($curview,$id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002264 if {$l1 <= $r && $r <= $l2} {
2265 return [expr {$r - $l1 + 1}]
2266 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002267 set kids [lindex $childlist $r]
2268 } else {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002269 set kids $children($curview,$id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002270 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002271 foreach c $kids {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002272 set r $commitrow($curview,$c)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002273 if {$l1 <= $r && $r <= $l2} {
2274 return [expr {$r - $l1 + 1}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002275 }
2276 }
2277 return 0
2278}
2279
2280proc sanity {row {full 0}} {
2281 global rowidlist rowoffsets
2282
2283 set col -1
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002284 set ids [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002285 foreach id $ids {
2286 incr col
2287 if {$id eq {}} continue
2288 if {$col < [llength $ids] - 1 &&
2289 [lsearch -exact -start [expr {$col+1}] $ids $id] >= 0} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002290 puts "oops: [shortids $id] repeated in row $row col $col: {[shortids [lindex $rowidlist $row]]}"
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002291 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002292 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002293 set y $row
2294 set x $col
2295 while {$o ne {}} {
2296 incr y -1
2297 incr x $o
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002298 if {[lindex $rowidlist $y $x] != $id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002299 puts "oops: rowoffsets wrong at row [expr {$y+1}] col [expr {$x-$o}]"
2300 puts " id=[shortids $id] check started at row $row"
2301 for {set i $row} {$i >= $y} {incr i -1} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002302 puts " row $i ids={[shortids [lindex $rowidlist $i]]} offs={[lindex $rowoffsets $i]}"
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002303 }
2304 break
2305 }
2306 if {!$full} break
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002307 set o [lindex $rowoffsets $y $x]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002308 }
2309 }
2310}
2311
2312proc makeuparrow {oid x y z} {
2313 global rowidlist rowoffsets uparrowlen idrowranges
2314
2315 for {set i 1} {$i < $uparrowlen && $y > 1} {incr i} {
2316 incr y -1
2317 incr x $z
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002318 set off0 [lindex $rowoffsets $y]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002319 for {set x0 $x} {1} {incr x0} {
2320 if {$x0 >= [llength $off0]} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002321 set x0 [llength [lindex $rowoffsets [expr {$y-1}]]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002322 break
2323 }
2324 set z [lindex $off0 $x0]
2325 if {$z ne {}} {
2326 incr x0 $z
2327 break
2328 }
2329 }
2330 set z [expr {$x0 - $x}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002331 lset rowidlist $y [linsert [lindex $rowidlist $y] $x $oid]
2332 lset rowoffsets $y [linsert [lindex $rowoffsets $y] $x $z]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002333 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002334 set tmp [lreplace [lindex $rowoffsets $y] $x $x {}]
2335 lset rowoffsets $y [incrange $tmp [expr {$x+1}] -1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002336 lappend idrowranges($oid) $y
2337}
2338
2339proc initlayout {} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10002340 global rowidlist rowoffsets displayorder commitlisted
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002341 global rowlaidout rowoptim
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002342 global idinlist rowchk rowrangelist idrowranges
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002343 global numcommits canvxmax canv
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002344 global nextcolor
Paul Mackerras79b2c752006-04-02 20:47:40 +10002345 global parentlist childlist children
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002346 global colormap rowtextx
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002347 global linesegends
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002348
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002349 set numcommits 0
2350 set displayorder {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002351 set commitlisted {}
2352 set parentlist {}
2353 set childlist {}
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002354 set rowrangelist {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002355 set nextcolor 0
2356 set rowidlist {{}}
2357 set rowoffsets {{}}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002358 catch {unset idinlist}
2359 catch {unset rowchk}
2360 set rowlaidout 0
2361 set rowoptim 0
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11002362 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002363 catch {unset colormap}
2364 catch {unset rowtextx}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002365 catch {unset idrowranges}
Paul Mackerras22626ef2006-04-17 09:56:02 +10002366 set linesegends {}
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11002367}
2368
2369proc setcanvscroll {} {
2370 global canv canv2 canv3 numcommits linespc canvxmax canvy0
2371
2372 set ymax [expr {$canvy0 + ($numcommits - 0.5) * $linespc + 2}]
2373 $canv conf -scrollregion [list 0 0 $canvxmax $ymax]
2374 $canv2 conf -scrollregion [list 0 0 0 $ymax]
2375 $canv3 conf -scrollregion [list 0 0 0 $ymax]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002376}
2377
2378proc visiblerows {} {
2379 global canv numcommits linespc
2380
2381 set ymax [lindex [$canv cget -scrollregion] 3]
2382 if {$ymax eq {} || $ymax == 0} return
2383 set f [$canv yview]
2384 set y0 [expr {int([lindex $f 0] * $ymax)}]
2385 set r0 [expr {int(($y0 - 3) / $linespc) - 1}]
2386 if {$r0 < 0} {
2387 set r0 0
2388 }
2389 set y1 [expr {int([lindex $f 1] * $ymax)}]
2390 set r1 [expr {int(($y1 - 3) / $linespc) + 1}]
2391 if {$r1 >= $numcommits} {
2392 set r1 [expr {$numcommits - 1}]
2393 }
2394 return [list $r0 $r1]
2395}
2396
Paul Mackerrasd1e46752006-08-16 20:02:32 +10002397proc layoutmore {tmax} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002398 global rowlaidout rowoptim commitidx numcommits optim_delay
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002399 global uparrowlen curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002400
Paul Mackerrasd1e46752006-08-16 20:02:32 +10002401 while {1} {
2402 if {$rowoptim - $optim_delay > $numcommits} {
2403 showstuff [expr {$rowoptim - $optim_delay}]
2404 } elseif {$rowlaidout - $uparrowlen - 1 > $rowoptim} {
2405 set nr [expr {$rowlaidout - $uparrowlen - 1 - $rowoptim}]
2406 if {$nr > 100} {
2407 set nr 100
2408 }
2409 optimize_rows $rowoptim 0 [expr {$rowoptim + $nr}]
2410 incr rowoptim $nr
2411 } elseif {$commitidx($curview) > $rowlaidout} {
2412 set nr [expr {$commitidx($curview) - $rowlaidout}]
2413 # may need to increase this threshold if uparrowlen or
2414 # mingaplen are increased...
2415 if {$nr > 150} {
2416 set nr 150
2417 }
2418 set row $rowlaidout
2419 set rowlaidout [layoutrows $row [expr {$row + $nr}] 0]
2420 if {$rowlaidout == $row} {
2421 return 0
2422 }
2423 } else {
2424 return 0
2425 }
2426 if {$tmax ne {} && [clock clicks -milliseconds] >= $tmax} {
2427 return 1
2428 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002429 }
2430}
2431
2432proc showstuff {canshow} {
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10002433 global numcommits commitrow pending_select selectedline
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002434 global linesegends idrowranges idrangedrawn curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002435
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002436 if {$numcommits == 0} {
2437 global phase
2438 set phase "incrdraw"
2439 allcanvs delete all
2440 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002441 set row $numcommits
2442 set numcommits $canshow
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11002443 setcanvscroll
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002444 set rows [visiblerows]
2445 set r0 [lindex $rows 0]
2446 set r1 [lindex $rows 1]
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002447 set selrow -1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002448 for {set r $row} {$r < $canshow} {incr r} {
Paul Mackerras22626ef2006-04-17 09:56:02 +10002449 foreach id [lindex $linesegends [expr {$r+1}]] {
2450 set i -1
2451 foreach {s e} [rowranges $id] {
2452 incr i
2453 if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0
2454 && ![info exists idrangedrawn($id,$i)]} {
2455 drawlineseg $id $i
2456 set idrangedrawn($id,$i) 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002457 }
2458 }
2459 }
2460 }
2461 if {$canshow > $r1} {
2462 set canshow $r1
2463 }
2464 while {$row < $canshow} {
2465 drawcmitrow $row
2466 incr row
2467 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002468 if {[info exists pending_select] &&
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002469 [info exists commitrow($curview,$pending_select)] &&
2470 $commitrow($curview,$pending_select) < $numcommits} {
2471 selectline $commitrow($curview,$pending_select) 1
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002472 }
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10002473 if {![info exists selectedline] && ![info exists pending_select]} {
2474 selectline 0 1
2475 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002476}
2477
2478proc layoutrows {row endrow last} {
2479 global rowidlist rowoffsets displayorder
2480 global uparrowlen downarrowlen maxwidth mingaplen
Paul Mackerras79b2c752006-04-02 20:47:40 +10002481 global childlist parentlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002482 global idrowranges linesegends
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002483 global commitidx curview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002484 global idinlist rowchk rowrangelist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002485
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002486 set idlist [lindex $rowidlist $row]
2487 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002488 while {$row < $endrow} {
2489 set id [lindex $displayorder $row]
2490 set oldolds {}
2491 set newolds {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002492 foreach p [lindex $parentlist $row] {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002493 if {![info exists idinlist($p)]} {
2494 lappend newolds $p
2495 } elseif {!$idinlist($p)} {
2496 lappend oldolds $p
2497 }
2498 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002499 set lse {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002500 set nev [expr {[llength $idlist] + [llength $newolds]
2501 + [llength $oldolds] - $maxwidth + 1}]
2502 if {$nev > 0} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002503 if {!$last &&
2504 $row + $uparrowlen + $mingaplen >= $commitidx($curview)} break
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002505 for {set x [llength $idlist]} {[incr x -1] >= 0} {} {
2506 set i [lindex $idlist $x]
2507 if {![info exists rowchk($i)] || $row >= $rowchk($i)} {
2508 set r [usedinrange $i [expr {$row - $downarrowlen}] \
2509 [expr {$row + $uparrowlen + $mingaplen}]]
2510 if {$r == 0} {
2511 set idlist [lreplace $idlist $x $x]
2512 set offs [lreplace $offs $x $x]
2513 set offs [incrange $offs $x 1]
2514 set idinlist($i) 0
Paul Mackerrasd8d2df02006-03-18 20:42:46 +11002515 set rm1 [expr {$row - 1}]
Paul Mackerras22626ef2006-04-17 09:56:02 +10002516 lappend lse $i
Paul Mackerrasd8d2df02006-03-18 20:42:46 +11002517 lappend idrowranges($i) $rm1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002518 if {[incr nev -1] <= 0} break
2519 continue
2520 }
2521 set rowchk($id) [expr {$row + $r}]
2522 }
2523 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002524 lset rowidlist $row $idlist
2525 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002526 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002527 lappend linesegends $lse
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002528 set col [lsearch -exact $idlist $id]
2529 if {$col < 0} {
2530 set col [llength $idlist]
2531 lappend idlist $id
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002532 lset rowidlist $row $idlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002533 set z {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002534 if {[lindex $childlist $row] ne {}} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002535 set z [expr {[llength [lindex $rowidlist [expr {$row-1}]]] - $col}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002536 unset idinlist($id)
2537 }
2538 lappend offs $z
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002539 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002540 if {$z ne {}} {
2541 makeuparrow $id $col $row $z
2542 }
2543 } else {
2544 unset idinlist($id)
2545 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002546 set ranges {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002547 if {[info exists idrowranges($id)]} {
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002548 set ranges $idrowranges($id)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002549 lappend ranges $row
2550 unset idrowranges($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002551 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002552 lappend rowrangelist $ranges
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002553 incr row
2554 set offs [ntimes [llength $idlist] 0]
2555 set l [llength $newolds]
2556 set idlist [eval lreplace \$idlist $col $col $newolds]
2557 set o 0
2558 if {$l != 1} {
2559 set offs [lrange $offs 0 [expr {$col - 1}]]
2560 foreach x $newolds {
2561 lappend offs {}
2562 incr o -1
2563 }
2564 incr o
2565 set tmp [expr {[llength $idlist] - [llength $offs]}]
2566 if {$tmp > 0} {
2567 set offs [concat $offs [ntimes $tmp $o]]
2568 }
2569 } else {
2570 lset offs $col {}
2571 }
2572 foreach i $newolds {
2573 set idinlist($i) 1
2574 set idrowranges($i) $row
2575 }
2576 incr col $l
2577 foreach oid $oldolds {
2578 set idinlist($oid) 1
2579 set idlist [linsert $idlist $col $oid]
2580 set offs [linsert $offs $col $o]
2581 makeuparrow $oid $col $row $o
2582 incr col
2583 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002584 lappend rowidlist $idlist
2585 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002586 }
2587 return $row
2588}
2589
2590proc addextraid {id row} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10002591 global displayorder commitrow commitinfo
Paul Mackerrase7da3472006-04-17 10:27:59 +10002592 global commitidx commitlisted
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002593 global parentlist childlist children curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002594
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002595 incr commitidx($curview)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002596 lappend displayorder $id
Paul Mackerrase7da3472006-04-17 10:27:59 +10002597 lappend commitlisted 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10002598 lappend parentlist {}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002599 set commitrow($curview,$id) $row
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002600 readcommit $id
2601 if {![info exists commitinfo($id)]} {
2602 set commitinfo($id) {"No commit information available"}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002603 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002604 if {![info exists children($curview,$id)]} {
2605 set children($curview,$id) {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002606 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002607 lappend childlist $children($curview,$id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002608}
2609
2610proc layouttail {} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002611 global rowidlist rowoffsets idinlist commitidx curview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002612 global idrowranges rowrangelist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002613
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002614 set row $commitidx($curview)
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002615 set idlist [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002616 while {$idlist ne {}} {
2617 set col [expr {[llength $idlist] - 1}]
2618 set id [lindex $idlist $col]
2619 addextraid $id $row
2620 unset idinlist($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002621 lappend idrowranges($id) $row
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002622 lappend rowrangelist $idrowranges($id)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002623 unset idrowranges($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002624 incr row
2625 set offs [ntimes $col 0]
2626 set idlist [lreplace $idlist $col $col]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002627 lappend rowidlist $idlist
2628 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002629 }
2630
2631 foreach id [array names idinlist] {
2632 addextraid $id $row
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002633 lset rowidlist $row [list $id]
2634 lset rowoffsets $row 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002635 makeuparrow $id 0 $row 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002636 lappend idrowranges($id) $row
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002637 lappend rowrangelist $idrowranges($id)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002638 unset idrowranges($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002639 incr row
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002640 lappend rowidlist {}
2641 lappend rowoffsets {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002642 }
2643}
2644
2645proc insert_pad {row col npad} {
2646 global rowidlist rowoffsets
2647
2648 set pad [ntimes $npad {}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002649 lset rowidlist $row [eval linsert [list [lindex $rowidlist $row]] $col $pad]
2650 set tmp [eval linsert [list [lindex $rowoffsets $row]] $col $pad]
2651 lset rowoffsets $row [incrange $tmp [expr {$col + $npad}] [expr {-$npad}]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002652}
2653
2654proc optimize_rows {row col endrow} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002655 global rowidlist rowoffsets idrowranges displayorder
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002656
2657 for {} {$row < $endrow} {incr row} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002658 set idlist [lindex $rowidlist $row]
2659 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002660 set haspad 0
2661 for {} {$col < [llength $offs]} {incr col} {
2662 if {[lindex $idlist $col] eq {}} {
2663 set haspad 1
2664 continue
2665 }
2666 set z [lindex $offs $col]
2667 if {$z eq {}} continue
2668 set isarrow 0
2669 set x0 [expr {$col + $z}]
2670 set y0 [expr {$row - 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002671 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002672 if {$z0 eq {}} {
2673 set id [lindex $idlist $col]
Paul Mackerras22626ef2006-04-17 09:56:02 +10002674 set ranges [rowranges $id]
2675 if {$ranges ne {} && $y0 > [lindex $ranges 0]} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002676 set isarrow 1
2677 }
2678 }
2679 if {$z < -1 || ($z < 0 && $isarrow)} {
2680 set npad [expr {-1 - $z + $isarrow}]
2681 set offs [incrange $offs $col $npad]
2682 insert_pad $y0 $x0 $npad
2683 if {$y0 > 0} {
2684 optimize_rows $y0 $x0 $row
2685 }
2686 set z [lindex $offs $col]
2687 set x0 [expr {$col + $z}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002688 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002689 } elseif {$z > 1 || ($z > 0 && $isarrow)} {
2690 set npad [expr {$z - 1 + $isarrow}]
2691 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002692 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002693 set x1 -1
2694 foreach z $offs2 {
2695 incr x1
2696 if {$z eq {} || $x1 + $z < $col} continue
2697 if {$x1 + $z > $col} {
2698 incr npad
2699 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002700 lset rowoffsets $y1 [incrange $offs2 $x1 $npad]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002701 break
2702 }
2703 set pad [ntimes $npad {}]
2704 set idlist [eval linsert \$idlist $col $pad]
2705 set tmp [eval linsert \$offs $col $pad]
2706 incr col $npad
2707 set offs [incrange $tmp $col [expr {-$npad}]]
2708 set z [lindex $offs $col]
2709 set haspad 1
2710 }
Paul Mackerraseb447a12006-03-18 23:11:37 +11002711 if {$z0 eq {} && !$isarrow} {
2712 # this line links to its first child on row $row-2
2713 set rm2 [expr {$row - 2}]
2714 set id [lindex $displayorder $rm2]
2715 set xc [lsearch -exact [lindex $rowidlist $rm2] $id]
2716 if {$xc >= 0} {
2717 set z0 [expr {$xc - $x0}]
2718 }
2719 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002720 if {$z0 ne {} && $z < 0 && $z0 > 0} {
2721 insert_pad $y0 $x0 1
2722 set offs [incrange $offs $col 1]
2723 optimize_rows $y0 [expr {$x0 + 1}] $row
2724 }
2725 }
2726 if {!$haspad} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11002727 set o {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002728 for {set col [llength $idlist]} {[incr col -1] >= 0} {} {
2729 set o [lindex $offs $col]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002730 if {$o eq {}} {
2731 # check if this is the link to the first child
2732 set id [lindex $idlist $col]
Paul Mackerras22626ef2006-04-17 09:56:02 +10002733 set ranges [rowranges $id]
2734 if {$ranges ne {} && $row == [lindex $ranges 0]} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11002735 # it is, work out offset to child
2736 set y0 [expr {$row - 1}]
2737 set id [lindex $displayorder $y0]
2738 set x0 [lsearch -exact [lindex $rowidlist $y0] $id]
2739 if {$x0 >= 0} {
2740 set o [expr {$x0 - $col}]
2741 }
2742 }
2743 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002744 if {$o eq {} || $o <= 0} break
2745 }
Paul Mackerraseb447a12006-03-18 23:11:37 +11002746 if {$o ne {} && [incr col] < [llength $idlist]} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002747 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002748 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002749 set x1 -1
2750 foreach z $offs2 {
2751 incr x1
2752 if {$z eq {} || $x1 + $z < $col} continue
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002753 lset rowoffsets $y1 [incrange $offs2 $x1 1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002754 break
2755 }
2756 set idlist [linsert $idlist $col {}]
2757 set tmp [linsert $offs $col {}]
2758 incr col
2759 set offs [incrange $tmp $col -1]
2760 }
2761 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002762 lset rowidlist $row $idlist
2763 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002764 set col 0
2765 }
2766}
2767
2768proc xc {row col} {
2769 global canvx0 linespc
2770 return [expr {$canvx0 + $col * $linespc}]
2771}
2772
2773proc yc {row} {
2774 global canvy0 linespc
2775 return [expr {$canvy0 + $row * $linespc}]
2776}
2777
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002778proc linewidth {id} {
2779 global thickerline lthickness
2780
2781 set wid $lthickness
2782 if {[info exists thickerline] && $id eq $thickerline} {
2783 set wid [expr {2 * $lthickness}]
2784 }
2785 return $wid
2786}
2787
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002788proc rowranges {id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002789 global phase idrowranges commitrow rowlaidout rowrangelist curview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002790
2791 set ranges {}
Paul Mackerras22626ef2006-04-17 09:56:02 +10002792 if {$phase eq {} ||
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002793 ([info exists commitrow($curview,$id)]
2794 && $commitrow($curview,$id) < $rowlaidout)} {
2795 set ranges [lindex $rowrangelist $commitrow($curview,$id)]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002796 } elseif {[info exists idrowranges($id)]} {
2797 set ranges $idrowranges($id)
2798 }
2799 return $ranges
2800}
2801
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002802proc drawlineseg {id i} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002803 global rowoffsets rowidlist
Paul Mackerraseb447a12006-03-18 23:11:37 +11002804 global displayorder
Paul Mackerras879e8b12006-03-31 10:45:14 +11002805 global canv colormap linespc
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002806 global numcommits commitrow curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002807
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002808 set ranges [rowranges $id]
2809 set downarrow 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002810 if {[info exists commitrow($curview,$id)]
2811 && $commitrow($curview,$id) < $numcommits} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002812 set downarrow [expr {$i < [llength $ranges] / 2 - 1}]
2813 } else {
2814 set downarrow 1
2815 }
2816 set startrow [lindex $ranges [expr {2 * $i}]]
2817 set row [lindex $ranges [expr {2 * $i + 1}]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002818 if {$startrow == $row} return
2819 assigncolor $id
2820 set coords {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002821 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002822 if {$col < 0} {
2823 puts "oops: drawline: id $id not on row $row"
2824 return
2825 }
2826 set lasto {}
2827 set ns 0
2828 while {1} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002829 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002830 if {$o eq {}} break
2831 if {$o ne $lasto} {
2832 # changing direction
2833 set x [xc $row $col]
2834 set y [yc $row]
2835 lappend coords $x $y
2836 set lasto $o
2837 }
2838 incr col $o
2839 incr row -1
2840 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002841 set x [xc $row $col]
2842 set y [yc $row]
2843 lappend coords $x $y
Paul Mackerraseb447a12006-03-18 23:11:37 +11002844 if {$i == 0} {
2845 # draw the link to the first child as part of this line
2846 incr row -1
2847 set child [lindex $displayorder $row]
2848 set ccol [lsearch -exact [lindex $rowidlist $row] $child]
2849 if {$ccol >= 0} {
2850 set x [xc $row $ccol]
2851 set y [yc $row]
2852 if {$ccol < $col - 1} {
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11002853 lappend coords [xc $row [expr {$col - 1}]] [yc $row]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002854 } elseif {$ccol > $col + 1} {
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11002855 lappend coords [xc $row [expr {$col + 1}]] [yc $row]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002856 }
2857 lappend coords $x $y
2858 }
2859 }
2860 if {[llength $coords] < 4} return
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002861 if {$downarrow} {
Paul Mackerras879e8b12006-03-31 10:45:14 +11002862 # This line has an arrow at the lower end: check if the arrow is
2863 # on a diagonal segment, and if so, work around the Tk 8.4
2864 # refusal to draw arrows on diagonal lines.
2865 set x0 [lindex $coords 0]
2866 set x1 [lindex $coords 2]
2867 if {$x0 != $x1} {
2868 set y0 [lindex $coords 1]
2869 set y1 [lindex $coords 3]
2870 if {$y0 - $y1 <= 2 * $linespc && $x1 == [lindex $coords 4]} {
2871 # we have a nearby vertical segment, just trim off the diag bit
2872 set coords [lrange $coords 2 end]
2873 } else {
2874 set slope [expr {($x0 - $x1) / ($y0 - $y1)}]
2875 set xi [expr {$x0 - $slope * $linespc / 2}]
2876 set yi [expr {$y0 - $linespc / 2}]
2877 set coords [lreplace $coords 0 1 $xi $y0 $xi $yi]
2878 }
2879 }
2880 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002881 set arrow [expr {2 * ($i > 0) + $downarrow}]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002882 set arrow [lindex {none first last both} $arrow]
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002883 set t [$canv create line $coords -width [linewidth $id] \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002884 -fill $colormap($id) -tags lines.$id -arrow $arrow]
2885 $canv lower $t
2886 bindline $t $id
2887}
2888
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002889proc drawparentlinks {id row col olds} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002890 global rowidlist canv colormap
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002891
2892 set row2 [expr {$row + 1}]
2893 set x [xc $row $col]
2894 set y [yc $row]
2895 set y2 [yc $row2]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002896 set ids [lindex $rowidlist $row2]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002897 # rmx = right-most X coord used
2898 set rmx 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002899 foreach p $olds {
Paul Mackerrasf3408442006-03-31 09:54:24 +11002900 set i [lsearch -exact $ids $p]
2901 if {$i < 0} {
2902 puts "oops, parent $p of $id not in list"
2903 continue
2904 }
2905 set x2 [xc $row2 $i]
2906 if {$x2 > $rmx} {
2907 set rmx $x2
2908 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002909 set ranges [rowranges $p]
2910 if {$ranges ne {} && $row2 == [lindex $ranges 0]
2911 && $row2 < [lindex $ranges 1]} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11002912 # drawlineseg will do this one for us
2913 continue
2914 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002915 assigncolor $p
2916 # should handle duplicated parents here...
2917 set coords [list $x $y]
2918 if {$i < $col - 1} {
2919 lappend coords [xc $row [expr {$i + 1}]] $y
2920 } elseif {$i > $col + 1} {
2921 lappend coords [xc $row [expr {$i - 1}]] $y
2922 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002923 lappend coords $x2 $y2
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002924 set t [$canv create line $coords -width [linewidth $p] \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002925 -fill $colormap($p) -tags lines.$p]
2926 $canv lower $t
2927 bindline $t $p
2928 }
2929 return $rmx
2930}
2931
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002932proc drawlines {id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002933 global colormap canv
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002934 global idrangedrawn
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002935 global children iddrawn commitrow rowidlist curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002936
2937 $canv delete lines.$id
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002938 set nr [expr {[llength [rowranges $id]] / 2}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002939 for {set i 0} {$i < $nr} {incr i} {
2940 if {[info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002941 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002942 }
2943 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002944 foreach child $children($curview,$id) {
Paul Mackerras79b2c752006-04-02 20:47:40 +10002945 if {[info exists iddrawn($child)]} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002946 set row $commitrow($curview,$child)
Paul Mackerras79b2c752006-04-02 20:47:40 +10002947 set col [lsearch -exact [lindex $rowidlist $row] $child]
2948 if {$col >= 0} {
2949 drawparentlinks $child $row $col [list $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002950 }
2951 }
2952 }
2953}
2954
2955proc drawcmittext {id row col rmx} {
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002956 global linespc canv canv2 canv3 canvy0 fgcolor
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002957 global commitlisted commitinfo rowidlist
2958 global rowtextx idpos idtags idheads idotherrefs
2959 global linehtag linentag linedtag
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002960 global mainfont canvxmax boldrows boldnamerows fgcolor
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002961
Paul Mackerras79b2c752006-04-02 20:47:40 +10002962 set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002963 set x [xc $row $col]
2964 set y [yc $row]
2965 set orad [expr {$linespc / 3}]
2966 set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
2967 [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002968 -fill $ofill -outline $fgcolor -width 1 -tags circle]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002969 $canv raise $t
2970 $canv bind $t <1> {selcanvline {} %x %y}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002971 set xt [xc $row [llength [lindex $rowidlist $row]]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002972 if {$xt < $rmx} {
2973 set xt $rmx
2974 }
2975 set rowtextx($row) $xt
2976 set idpos($id) [list $x $xt $y]
2977 if {[info exists idtags($id)] || [info exists idheads($id)]
2978 || [info exists idotherrefs($id)]} {
2979 set xt [drawtags $id $x $xt $y]
2980 }
2981 set headline [lindex $commitinfo($id) 0]
2982 set name [lindex $commitinfo($id) 1]
2983 set date [lindex $commitinfo($id) 2]
2984 set date [formatdate $date]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002985 set font $mainfont
Paul Mackerras908c3582006-05-20 09:38:11 +10002986 set nfont $mainfont
2987 set isbold [ishighlighted $row]
2988 if {$isbold > 0} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002989 lappend boldrows $row
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002990 lappend font bold
Paul Mackerras908c3582006-05-20 09:38:11 +10002991 if {$isbold > 1} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002992 lappend boldnamerows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10002993 lappend nfont bold
2994 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002995 }
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002996 set linehtag($row) [$canv create text $xt $y -anchor w -fill $fgcolor \
2997 -text $headline -font $font -tags text]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002998 $canv bind $linehtag($row) <Button-3> "rowmenu %X %Y $id"
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002999 set linentag($row) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
3000 -text $name -font $nfont -tags text]
3001 set linedtag($row) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
3002 -text $date -font $mainfont -tags text]
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11003003 set xr [expr {$xt + [font measure $mainfont $headline]}]
3004 if {$xr > $canvxmax} {
3005 set canvxmax $xr
3006 setcanvscroll
3007 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003008}
3009
3010proc drawcmitrow {row} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003011 global displayorder rowidlist
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003012 global idrangedrawn iddrawn
Paul Mackerrase7da3472006-04-17 10:27:59 +10003013 global commitinfo parentlist numcommits
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003014 global filehighlight fhighlights findstring nhighlights
Paul Mackerras908c3582006-05-20 09:38:11 +10003015 global hlview vhighlights
Paul Mackerras164ff272006-05-29 19:50:02 +10003016 global highlight_related rhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003017
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003018 if {$row >= $numcommits} return
3019 foreach id [lindex $rowidlist $row] {
Paul Mackerras22626ef2006-04-17 09:56:02 +10003020 if {$id eq {}} continue
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003021 set i -1
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003022 foreach {s e} [rowranges $id] {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003023 incr i
3024 if {$row < $s} continue
3025 if {$e eq {}} break
3026 if {$row <= $e} {
3027 if {$e < $numcommits && ![info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11003028 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003029 set idrangedrawn($id,$i) 1
3030 }
3031 break
3032 }
3033 }
3034 }
3035
3036 set id [lindex $displayorder $row]
Paul Mackerras908c3582006-05-20 09:38:11 +10003037 if {[info exists hlview] && ![info exists vhighlights($row)]} {
3038 askvhighlight $row $id
3039 }
3040 if {[info exists filehighlight] && ![info exists fhighlights($row)]} {
3041 askfilehighlight $row $id
3042 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003043 if {$findstring ne {} && ![info exists nhighlights($row)]} {
3044 askfindhighlight $row $id
Paul Mackerras908c3582006-05-20 09:38:11 +10003045 }
Paul Mackerras164ff272006-05-29 19:50:02 +10003046 if {$highlight_related ne "None" && ![info exists rhighlights($row)]} {
3047 askrelhighlight $row $id
3048 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003049 if {[info exists iddrawn($id)]} return
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003050 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003051 if {$col < 0} {
3052 puts "oops, row $row id $id not in list"
3053 return
3054 }
3055 if {![info exists commitinfo($id)]} {
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11003056 getcommit $id
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003057 }
3058 assigncolor $id
Paul Mackerras79b2c752006-04-02 20:47:40 +10003059 set olds [lindex $parentlist $row]
3060 if {$olds ne {}} {
3061 set rmx [drawparentlinks $id $row $col $olds]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003062 } else {
3063 set rmx 0
3064 }
3065 drawcmittext $id $row $col $rmx
3066 set iddrawn($id) 1
3067}
3068
3069proc drawfrac {f0 f1} {
3070 global numcommits canv
3071 global linespc
3072
3073 set ymax [lindex [$canv cget -scrollregion] 3]
3074 if {$ymax eq {} || $ymax == 0} return
3075 set y0 [expr {int($f0 * $ymax)}]
3076 set row [expr {int(($y0 - 3) / $linespc) - 1}]
3077 if {$row < 0} {
3078 set row 0
3079 }
3080 set y1 [expr {int($f1 * $ymax)}]
3081 set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
3082 if {$endrow >= $numcommits} {
3083 set endrow [expr {$numcommits - 1}]
3084 }
3085 for {} {$row <= $endrow} {incr row} {
3086 drawcmitrow $row
3087 }
3088}
3089
3090proc drawvisible {} {
3091 global canv
3092 eval drawfrac [$canv yview]
3093}
3094
3095proc clear_display {} {
3096 global iddrawn idrangedrawn
Paul Mackerras164ff272006-05-29 19:50:02 +10003097 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003098
3099 allcanvs delete all
3100 catch {unset iddrawn}
3101 catch {unset idrangedrawn}
Paul Mackerras908c3582006-05-20 09:38:11 +10003102 catch {unset vhighlights}
3103 catch {unset fhighlights}
3104 catch {unset nhighlights}
Paul Mackerras164ff272006-05-29 19:50:02 +10003105 catch {unset rhighlights}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003106}
3107
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003108proc findcrossings {id} {
3109 global rowidlist parentlist numcommits rowoffsets displayorder
3110
3111 set cross {}
3112 set ccross {}
3113 foreach {s e} [rowranges $id] {
3114 if {$e >= $numcommits} {
3115 set e [expr {$numcommits - 1}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003116 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003117 if {$e <= $s} continue
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003118 set x [lsearch -exact [lindex $rowidlist $e] $id]
3119 if {$x < 0} {
3120 puts "findcrossings: oops, no [shortids $id] in row $e"
3121 continue
3122 }
3123 for {set row $e} {[incr row -1] >= $s} {} {
3124 set olds [lindex $parentlist $row]
3125 set kid [lindex $displayorder $row]
3126 set kidx [lsearch -exact [lindex $rowidlist $row] $kid]
3127 if {$kidx < 0} continue
3128 set nextrow [lindex $rowidlist [expr {$row + 1}]]
3129 foreach p $olds {
3130 set px [lsearch -exact $nextrow $p]
3131 if {$px < 0} continue
3132 if {($kidx < $x && $x < $px) || ($px < $x && $x < $kidx)} {
3133 if {[lsearch -exact $ccross $p] >= 0} continue
3134 if {$x == $px + ($kidx < $px? -1: 1)} {
3135 lappend ccross $p
3136 } elseif {[lsearch -exact $cross $p] < 0} {
3137 lappend cross $p
3138 }
3139 }
3140 }
3141 set inc [lindex $rowoffsets $row $x]
3142 if {$inc eq {}} break
3143 incr x $inc
3144 }
3145 }
3146 return [concat $ccross {{}} $cross]
3147}
3148
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003149proc assigncolor {id} {
Paul Mackerrasaa81d972006-02-28 11:27:12 +11003150 global colormap colors nextcolor
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003151 global commitrow parentlist children children curview
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003152
Paul Mackerras418c4c72006-02-07 09:10:18 +11003153 if {[info exists colormap($id)]} return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003154 set ncolors [llength $colors]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003155 if {[info exists children($curview,$id)]} {
3156 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 20:47:40 +10003157 } else {
3158 set kids {}
3159 }
3160 if {[llength $kids] == 1} {
3161 set child [lindex $kids 0]
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003162 if {[info exists colormap($child)]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003163 && [llength [lindex $parentlist $commitrow($curview,$child)]] == 1} {
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003164 set colormap($id) $colormap($child)
3165 return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003166 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003167 }
3168 set badcolors {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003169 set origbad {}
3170 foreach x [findcrossings $id] {
3171 if {$x eq {}} {
3172 # delimiter between corner crossings and other crossings
3173 if {[llength $badcolors] >= $ncolors - 1} break
3174 set origbad $badcolors
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003175 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003176 if {[info exists colormap($x)]
3177 && [lsearch -exact $badcolors $colormap($x)] < 0} {
3178 lappend badcolors $colormap($x)
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003179 }
3180 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003181 if {[llength $badcolors] >= $ncolors} {
3182 set badcolors $origbad
3183 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003184 set origbad $badcolors
3185 if {[llength $badcolors] < $ncolors - 1} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003186 foreach child $kids {
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003187 if {[info exists colormap($child)]
3188 && [lsearch -exact $badcolors $colormap($child)] < 0} {
3189 lappend badcolors $colormap($child)
3190 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003191 foreach p [lindex $parentlist $commitrow($curview,$child)] {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003192 if {[info exists colormap($p)]
3193 && [lsearch -exact $badcolors $colormap($p)] < 0} {
3194 lappend badcolors $colormap($p)
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003195 }
3196 }
3197 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003198 if {[llength $badcolors] >= $ncolors} {
3199 set badcolors $origbad
3200 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003201 }
3202 for {set i 0} {$i <= $ncolors} {incr i} {
3203 set c [lindex $colors $nextcolor]
3204 if {[incr nextcolor] >= $ncolors} {
3205 set nextcolor 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003206 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003207 if {[lsearch -exact $badcolors $c]} break
3208 }
3209 set colormap($id) $c
3210}
3211
Paul Mackerrasa823a912005-06-21 10:01:38 +10003212proc bindline {t id} {
3213 global canv
3214
Paul Mackerrasa823a912005-06-21 10:01:38 +10003215 $canv bind $t <Enter> "lineenter %x %y $id"
3216 $canv bind $t <Motion> "linemotion %x %y $id"
3217 $canv bind $t <Leave> "lineleave $id"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003218 $canv bind $t <Button-1> "lineclick %x %y $id 1"
Paul Mackerrasa823a912005-06-21 10:01:38 +10003219}
3220
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003221proc drawtags {id x xt y1} {
Paul Mackerras8a485712006-07-06 10:21:23 +10003222 global idtags idheads idotherrefs mainhead
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003223 global linespc lthickness
Paul Mackerras8a485712006-07-06 10:21:23 +10003224 global canv mainfont commitrow rowtextx curview fgcolor bgcolor
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003225
3226 set marks {}
3227 set ntags 0
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003228 set nheads 0
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003229 if {[info exists idtags($id)]} {
3230 set marks $idtags($id)
3231 set ntags [llength $marks]
3232 }
3233 if {[info exists idheads($id)]} {
3234 set marks [concat $marks $idheads($id)]
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003235 set nheads [llength $idheads($id)]
3236 }
3237 if {[info exists idotherrefs($id)]} {
3238 set marks [concat $marks $idotherrefs($id)]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003239 }
3240 if {$marks eq {}} {
3241 return $xt
3242 }
3243
3244 set delta [expr {int(0.5 * ($linespc - $lthickness))}]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003245 set yt [expr {$y1 - 0.5 * $linespc}]
3246 set yb [expr {$yt + $linespc - 1}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003247 set xvals {}
3248 set wvals {}
Paul Mackerras8a485712006-07-06 10:21:23 +10003249 set i -1
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003250 foreach tag $marks {
Paul Mackerras8a485712006-07-06 10:21:23 +10003251 incr i
3252 if {$i >= $ntags && $i < $ntags + $nheads && $tag eq $mainhead} {
3253 set wid [font measure [concat $mainfont bold] $tag]
3254 } else {
3255 set wid [font measure $mainfont $tag]
3256 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003257 lappend xvals $xt
3258 lappend wvals $wid
3259 set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
3260 }
3261 set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
3262 -width $lthickness -fill black -tags tag.$id]
3263 $canv lower $t
3264 foreach tag $marks x $xvals wid $wvals {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003265 set xl [expr {$x + $delta}]
3266 set xr [expr {$x + $delta + $wid + $lthickness}]
Paul Mackerras8a485712006-07-06 10:21:23 +10003267 set font $mainfont
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003268 if {[incr ntags -1] >= 0} {
3269 # draw a tag
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003270 set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
3271 $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
Paul Mackerras106288c2005-08-19 23:11:39 +10003272 -width 1 -outline black -fill yellow -tags tag.$id]
3273 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003274 set rowtextx($commitrow($curview,$id)) [expr {$xr + $linespc}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003275 } else {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003276 # draw a head or other ref
3277 if {[incr nheads -1] >= 0} {
3278 set col green
Paul Mackerras8a485712006-07-06 10:21:23 +10003279 if {$tag eq $mainhead} {
3280 lappend font bold
3281 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003282 } else {
3283 set col "#ddddff"
3284 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003285 set xl [expr {$xl - $delta/2}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003286 $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003287 -width 1 -outline black -fill $col -tags tag.$id
Josef Weidendorfera970fcf2006-04-18 23:53:07 +02003288 if {[regexp {^(remotes/.*/|remotes/)} $tag match remoteprefix]} {
3289 set rwid [font measure $mainfont $remoteprefix]
3290 set xi [expr {$x + 1}]
3291 set yti [expr {$yt + 1}]
3292 set xri [expr {$x + $rwid}]
3293 $canv create polygon $xi $yti $xri $yti $xri $yb $xi $yb \
3294 -width 0 -fill "#ffddaa" -tags tag.$id
3295 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003296 }
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003297 set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \
Paul Mackerras8a485712006-07-06 10:21:23 +10003298 -font $font -tags [list tag.$id text]]
Paul Mackerras106288c2005-08-19 23:11:39 +10003299 if {$ntags >= 0} {
3300 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerras10299152006-08-02 09:52:01 +10003301 } elseif {$nheads >= 0} {
3302 $canv bind $t <Button-3> [list headmenu %X %Y $id $tag]
Paul Mackerras106288c2005-08-19 23:11:39 +10003303 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003304 }
3305 return $xt
3306}
3307
Paul Mackerras8d858d12005-08-05 09:52:16 +10003308proc xcoord {i level ln} {
3309 global canvx0 xspc1 xspc2
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003310
Paul Mackerras8d858d12005-08-05 09:52:16 +10003311 set x [expr {$canvx0 + $i * $xspc1($ln)}]
3312 if {$i > 0 && $i == $level} {
3313 set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
3314 } elseif {$i > $level} {
3315 set x [expr {$x + $xspc2 - $xspc1($ln)}]
3316 }
3317 return $x
3318}
3319
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003320proc show_status {msg} {
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003321 global canv mainfont fgcolor
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003322
3323 clear_display
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003324 $canv create text 3 3 -anchor nw -text $msg -font $mainfont \
3325 -tags text -fill $fgcolor
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003326}
3327
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003328proc finishcommits {} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003329 global commitidx phase curview
Paul Mackerrase1a7c812006-07-18 01:52:14 +10003330 global pending_select
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003331
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003332 if {$commitidx($curview) > 0} {
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01003333 drawrest
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01003334 } else {
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003335 show_status "No commits selected"
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003336 }
Paul Mackerras8ed16482006-03-02 22:56:44 +11003337 set phase {}
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003338 catch {unset pending_select}
Paul Mackerras94a2eed2005-08-07 15:27:57 +10003339}
3340
Paul Mackerras561d0382006-08-28 22:41:09 +10003341# Insert a new commit as the child of the commit on row $row.
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003342# The new commit will be displayed on row $row and the commits
3343# on that row and below will move down one row.
3344proc insertrow {row newcmit} {
3345 global displayorder parentlist childlist commitlisted
3346 global commitrow curview rowidlist rowoffsets numcommits
3347 global rowrangelist idrowranges rowlaidout rowoptim numcommits
Paul Mackerras561d0382006-08-28 22:41:09 +10003348 global linesegends selectedline
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003349
3350 if {$row >= $numcommits} {
3351 puts "oops, inserting new row $row but only have $numcommits rows"
3352 return
3353 }
3354 set p [lindex $displayorder $row]
3355 set displayorder [linsert $displayorder $row $newcmit]
3356 set parentlist [linsert $parentlist $row $p]
3357 set kids [lindex $childlist $row]
3358 lappend kids $newcmit
3359 lset childlist $row $kids
3360 set childlist [linsert $childlist $row {}]
Paul Mackerras561d0382006-08-28 22:41:09 +10003361 set commitlisted [linsert $commitlisted $row 1]
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003362 set l [llength $displayorder]
3363 for {set r $row} {$r < $l} {incr r} {
3364 set id [lindex $displayorder $r]
3365 set commitrow($curview,$id) $r
3366 }
3367
3368 set idlist [lindex $rowidlist $row]
3369 set offs [lindex $rowoffsets $row]
3370 set newoffs {}
3371 foreach x $idlist {
3372 if {$x eq {} || ($x eq $p && [llength $kids] == 1)} {
3373 lappend newoffs {}
3374 } else {
3375 lappend newoffs 0
3376 }
3377 }
3378 if {[llength $kids] == 1} {
3379 set col [lsearch -exact $idlist $p]
3380 lset idlist $col $newcmit
3381 } else {
3382 set col [llength $idlist]
3383 lappend idlist $newcmit
3384 lappend offs {}
3385 lset rowoffsets $row $offs
3386 }
3387 set rowidlist [linsert $rowidlist $row $idlist]
3388 set rowoffsets [linsert $rowoffsets [expr {$row+1}] $newoffs]
3389
3390 set rowrangelist [linsert $rowrangelist $row {}]
3391 set l [llength $rowrangelist]
3392 for {set r 0} {$r < $l} {incr r} {
3393 set ranges [lindex $rowrangelist $r]
3394 if {$ranges ne {} && [lindex $ranges end] >= $row} {
3395 set newranges {}
3396 foreach x $ranges {
3397 if {$x >= $row} {
3398 lappend newranges [expr {$x + 1}]
3399 } else {
3400 lappend newranges $x
3401 }
3402 }
3403 lset rowrangelist $r $newranges
3404 }
3405 }
3406 if {[llength $kids] > 1} {
3407 set rp1 [expr {$row + 1}]
3408 set ranges [lindex $rowrangelist $rp1]
3409 if {$ranges eq {}} {
3410 set ranges [list $row $rp1]
3411 } elseif {[lindex $ranges end-1] == $rp1} {
3412 lset ranges end-1 $row
3413 }
3414 lset rowrangelist $rp1 $ranges
3415 }
3416 foreach id [array names idrowranges] {
3417 set ranges $idrowranges($id)
3418 if {$ranges ne {} && [lindex $ranges end] >= $row} {
3419 set newranges {}
3420 foreach x $ranges {
3421 if {$x >= $row} {
3422 lappend newranges [expr {$x + 1}]
3423 } else {
3424 lappend newranges $x
3425 }
3426 }
3427 set idrowranges($id) $newranges
3428 }
3429 }
3430
3431 set linesegends [linsert $linesegends $row {}]
3432
3433 incr rowlaidout
3434 incr rowoptim
3435 incr numcommits
3436
Paul Mackerras561d0382006-08-28 22:41:09 +10003437 if {[info exists selectedline] && $selectedline >= $row} {
3438 incr selectedline
3439 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003440 redisplay
3441}
3442
Paul Mackerras94a2eed2005-08-07 15:27:57 +10003443# Don't change the text pane cursor if it is currently the hand cursor,
3444# showing that we are over a sha1 ID link.
3445proc settextcursor {c} {
3446 global ctext curtextcursor
3447
3448 if {[$ctext cget -cursor] == $curtextcursor} {
3449 $ctext config -cursor $c
3450 }
3451 set curtextcursor $c
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003452}
3453
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003454proc nowbusy {what} {
3455 global isbusy
3456
3457 if {[array names isbusy] eq {}} {
3458 . config -cursor watch
3459 settextcursor watch
3460 }
3461 set isbusy($what) 1
3462}
3463
3464proc notbusy {what} {
3465 global isbusy maincursor textcursor
3466
3467 catch {unset isbusy($what)}
3468 if {[array names isbusy] eq {}} {
3469 . config -cursor $maincursor
3470 settextcursor $textcursor
3471 }
3472}
3473
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10003474proc drawrest {} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003475 global startmsecs
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003476 global rowlaidout commitidx curview
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003477 global pending_select
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003478
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003479 set row $rowlaidout
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003480 layoutrows $rowlaidout $commitidx($curview) 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003481 layouttail
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003482 optimize_rows $row 0 $commitidx($curview)
3483 showstuff $commitidx($curview)
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003484 if {[info exists pending_select]} {
3485 selectline 0 1
3486 }
Paul Mackerras4dd5d0d2005-12-06 09:46:23 +11003487
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003488 set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}]
Paul Mackerrase1a7c812006-07-18 01:52:14 +10003489 #global numcommits
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10003490 #puts "overall $drawmsecs ms for $numcommits commits"
Paul Mackerras1db95b02005-05-09 04:08:39 +00003491}
3492
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003493proc findmatches {f} {
3494 global findtype foundstring foundstrlen
3495 if {$findtype == "Regexp"} {
3496 set matches [regexp -indices -all -inline $foundstring $f]
3497 } else {
3498 if {$findtype == "IgnCase"} {
3499 set str [string tolower $f]
3500 } else {
3501 set str $f
3502 }
3503 set matches {}
3504 set i 0
3505 while {[set j [string first $foundstring $str $i]] >= 0} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003506 lappend matches [list $j [expr {$j+$foundstrlen-1}]]
3507 set i [expr {$j + $foundstrlen}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003508 }
3509 }
3510 return $matches
3511}
3512
Paul Mackerras98f350e2005-05-15 05:56:51 +00003513proc dofind {} {
3514 global findtype findloc findstring markedmatches commitinfo
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003515 global numcommits displayorder linehtag linentag linedtag
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003516 global mainfont canv canv2 canv3 selectedline
Paul Mackerras8ed16482006-03-02 22:56:44 +11003517 global matchinglines foundstring foundstrlen matchstring
3518 global commitdata
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003519
3520 stopfindproc
Paul Mackerras98f350e2005-05-15 05:56:51 +00003521 unmarkmatches
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003522 cancel_next_highlight
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003523 focus .
Paul Mackerras98f350e2005-05-15 05:56:51 +00003524 set matchinglines {}
Paul Mackerras98f350e2005-05-15 05:56:51 +00003525 if {$findtype == "IgnCase"} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003526 set foundstring [string tolower $findstring]
Paul Mackerras98f350e2005-05-15 05:56:51 +00003527 } else {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003528 set foundstring $findstring
Paul Mackerras98f350e2005-05-15 05:56:51 +00003529 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003530 set foundstrlen [string length $findstring]
3531 if {$foundstrlen == 0} return
Paul Mackerras8ed16482006-03-02 22:56:44 +11003532 regsub -all {[*?\[\\]} $foundstring {\\&} matchstring
3533 set matchstring "*$matchstring*"
Paul Mackerras98f350e2005-05-15 05:56:51 +00003534 if {![info exists selectedline]} {
3535 set oldsel -1
3536 } else {
3537 set oldsel $selectedline
3538 }
3539 set didsel 0
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003540 set fldtypes {Headline Author Date Committer CDate Comments}
Paul Mackerras8ed16482006-03-02 22:56:44 +11003541 set l -1
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11003542 foreach id $displayorder {
3543 set d $commitdata($id)
Paul Mackerras8ed16482006-03-02 22:56:44 +11003544 incr l
3545 if {$findtype == "Regexp"} {
3546 set doesmatch [regexp $foundstring $d]
3547 } elseif {$findtype == "IgnCase"} {
3548 set doesmatch [string match -nocase $matchstring $d]
3549 } else {
3550 set doesmatch [string match $matchstring $d]
3551 }
3552 if {!$doesmatch} continue
Paul Mackerras8ed16482006-03-02 22:56:44 +11003553 if {![info exists commitinfo($id)]} {
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11003554 getcommit $id
Paul Mackerras8ed16482006-03-02 22:56:44 +11003555 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003556 set info $commitinfo($id)
3557 set doesmatch 0
3558 foreach f $info ty $fldtypes {
3559 if {$findloc != "All fields" && $findloc != $ty} {
3560 continue
3561 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003562 set matches [findmatches $f]
Paul Mackerras98f350e2005-05-15 05:56:51 +00003563 if {$matches == {}} continue
3564 set doesmatch 1
3565 if {$ty == "Headline"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003566 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003567 markmatches $canv $l $f $linehtag($l) $matches $mainfont
3568 } elseif {$ty == "Author"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003569 drawcmitrow $l
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003570 markmatches $canv2 $l $f $linentag($l) $matches $mainfont
Paul Mackerras98f350e2005-05-15 05:56:51 +00003571 } elseif {$ty == "Date"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003572 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003573 markmatches $canv3 $l $f $linedtag($l) $matches $mainfont
3574 }
3575 }
3576 if {$doesmatch} {
3577 lappend matchinglines $l
3578 if {!$didsel && $l > $oldsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003579 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003580 set didsel 1
3581 }
3582 }
3583 }
3584 if {$matchinglines == {}} {
3585 bell
3586 } elseif {!$didsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003587 findselectline [lindex $matchinglines 0]
3588 }
3589}
3590
3591proc findselectline {l} {
3592 global findloc commentend ctext
Paul Mackerrasd6982062005-08-06 22:06:06 +10003593 selectline $l 1
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003594 if {$findloc == "All fields" || $findloc == "Comments"} {
3595 # highlight the matches in the comments
3596 set f [$ctext get 1.0 $commentend]
3597 set matches [findmatches $f]
3598 foreach match $matches {
3599 set start [lindex $match 0]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003600 set end [expr {[lindex $match 1] + 1}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003601 $ctext tag add found "1.0 + $start c" "1.0 + $end c"
3602 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003603 }
3604}
3605
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003606proc findnext {restart} {
Paul Mackerras98f350e2005-05-15 05:56:51 +00003607 global matchinglines selectedline
3608 if {![info exists matchinglines]} {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003609 if {$restart} {
3610 dofind
3611 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003612 return
3613 }
3614 if {![info exists selectedline]} return
3615 foreach l $matchinglines {
3616 if {$l > $selectedline} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003617 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003618 return
3619 }
3620 }
3621 bell
3622}
3623
3624proc findprev {} {
3625 global matchinglines selectedline
3626 if {![info exists matchinglines]} {
3627 dofind
3628 return
3629 }
3630 if {![info exists selectedline]} return
3631 set prev {}
3632 foreach l $matchinglines {
3633 if {$l >= $selectedline} break
3634 set prev $l
3635 }
3636 if {$prev != {}} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003637 findselectline $prev
Paul Mackerras98f350e2005-05-15 05:56:51 +00003638 } else {
3639 bell
3640 }
3641}
3642
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003643proc stopfindproc {{done 0}} {
3644 global findprocpid findprocfile findids
3645 global ctext findoldcursor phase maincursor textcursor
3646 global findinprogress
3647
3648 catch {unset findids}
3649 if {[info exists findprocpid]} {
3650 if {!$done} {
3651 catch {exec kill $findprocpid}
3652 }
3653 catch {close $findprocfile}
3654 unset findprocpid
3655 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003656 catch {unset findinprogress}
3657 notbusy find
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003658}
3659
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003660# mark a commit as matching by putting a yellow background
3661# behind the headline
3662proc markheadline {l id} {
Paul Mackerras8ed16482006-03-02 22:56:44 +11003663 global canv mainfont linehtag
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003664
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003665 drawcmitrow $l
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003666 set bbox [$canv bbox $linehtag($l)]
3667 set t [$canv create rect $bbox -outline {} -tags matches -fill yellow]
3668 $canv lower $t
3669}
3670
3671# mark the bits of a headline, author or date that match a find string
Paul Mackerras98f350e2005-05-15 05:56:51 +00003672proc markmatches {canv l str tag matches font} {
3673 set bbox [$canv bbox $tag]
3674 set x0 [lindex $bbox 0]
3675 set y0 [lindex $bbox 1]
3676 set y1 [lindex $bbox 3]
3677 foreach match $matches {
3678 set start [lindex $match 0]
3679 set end [lindex $match 1]
3680 if {$start > $end} continue
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003681 set xoff [font measure $font [string range $str 0 [expr {$start-1}]]]
3682 set xlen [font measure $font [string range $str 0 [expr {$end}]]]
3683 set t [$canv create rect [expr {$x0+$xoff}] $y0 \
3684 [expr {$x0+$xlen+2}] $y1 \
Paul Mackerras98f350e2005-05-15 05:56:51 +00003685 -outline {} -tags matches -fill yellow]
3686 $canv lower $t
3687 }
3688}
3689
3690proc unmarkmatches {} {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003691 global matchinglines findids
Paul Mackerras98f350e2005-05-15 05:56:51 +00003692 allcanvs delete matches
3693 catch {unset matchinglines}
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003694 catch {unset findids}
Paul Mackerras98f350e2005-05-15 05:56:51 +00003695}
3696
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003697proc selcanvline {w x y} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003698 global canv canvy0 ctext linespc
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003699 global rowtextx
Paul Mackerras1db95b02005-05-09 04:08:39 +00003700 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerrascfb45632005-05-31 12:14:42 +00003701 if {$ymax == {}} return
Paul Mackerras1db95b02005-05-09 04:08:39 +00003702 set yfrac [lindex [$canv yview] 0]
3703 set y [expr {$y + $yfrac * $ymax}]
3704 set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
3705 if {$l < 0} {
3706 set l 0
3707 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003708 if {$w eq $canv} {
3709 if {![info exists rowtextx($l)] || $x < $rowtextx($l)} return
3710 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003711 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10003712 selectline $l 1
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003713}
3714
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003715proc commit_descriptor {p} {
3716 global commitinfo
Paul Mackerrasb0934482006-05-15 09:56:08 +10003717 if {![info exists commitinfo($p)]} {
3718 getcommit $p
3719 }
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003720 set l "..."
Paul Mackerrasb0934482006-05-15 09:56:08 +10003721 if {[llength $commitinfo($p)] > 1} {
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003722 set l [lindex $commitinfo($p) 0]
3723 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003724 return "$p ($l)\n"
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003725}
3726
Paul Mackerras106288c2005-08-19 23:11:39 +10003727# append some text to the ctext widget, and make any SHA1 ID
3728# that we know about be a clickable link.
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003729proc appendwithlinks {text tags} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003730 global ctext commitrow linknum curview
Paul Mackerras106288c2005-08-19 23:11:39 +10003731
3732 set start [$ctext index "end - 1c"]
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003733 $ctext insert end $text $tags
Paul Mackerras106288c2005-08-19 23:11:39 +10003734 set links [regexp -indices -all -inline {[0-9a-f]{40}} $text]
3735 foreach l $links {
3736 set s [lindex $l 0]
3737 set e [lindex $l 1]
3738 set linkid [string range $text $s $e]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003739 if {![info exists commitrow($curview,$linkid)]} continue
Paul Mackerras106288c2005-08-19 23:11:39 +10003740 incr e
3741 $ctext tag add link "$start + $s c" "$start + $e c"
3742 $ctext tag add link$linknum "$start + $s c" "$start + $e c"
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003743 $ctext tag bind link$linknum <1> \
3744 [list selectline $commitrow($curview,$linkid) 1]
Paul Mackerras106288c2005-08-19 23:11:39 +10003745 incr linknum
3746 }
3747 $ctext tag conf link -foreground blue -underline 1
3748 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
3749 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
3750}
3751
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10003752proc viewnextline {dir} {
3753 global canv linespc
3754
3755 $canv delete hover
3756 set ymax [lindex [$canv cget -scrollregion] 3]
3757 set wnow [$canv yview]
3758 set wtop [expr {[lindex $wnow 0] * $ymax}]
3759 set newtop [expr {$wtop + $dir * $linespc}]
3760 if {$newtop < 0} {
3761 set newtop 0
3762 } elseif {$newtop > $ymax} {
3763 set newtop $ymax
3764 }
3765 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
3766}
3767
Paul Mackerrasef030b82006-06-04 11:50:38 +10003768# add a list of tag or branch names at position pos
3769# returns the number of names inserted
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003770proc appendrefs {pos tags var} {
3771 global ctext commitrow linknum curview $var
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003772
Paul Mackerrasef030b82006-06-04 11:50:38 +10003773 if {[catch {$ctext index $pos}]} {
3774 return 0
3775 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003776 set tags [lsort $tags]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003777 set sep {}
3778 foreach tag $tags {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003779 set id [set $var\($tag\)]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003780 set lk link$linknum
3781 incr linknum
3782 $ctext insert $pos $sep
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003783 $ctext insert $pos $tag $lk
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003784 $ctext tag conf $lk -foreground blue
3785 if {[info exists commitrow($curview,$id)]} {
3786 $ctext tag bind $lk <1> \
3787 [list selectline $commitrow($curview,$id) 1]
3788 $ctext tag conf $lk -underline 1
3789 $ctext tag bind $lk <Enter> { %W configure -cursor hand2 }
3790 $ctext tag bind $lk <Leave> { %W configure -cursor $curtextcursor }
3791 }
3792 set sep ", "
3793 }
Paul Mackerrasef030b82006-06-04 11:50:38 +10003794 return [llength $tags]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003795}
3796
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003797proc taglist {ids} {
3798 global idtags
3799
3800 set tags {}
3801 foreach id $ids {
3802 foreach tag $idtags($id) {
3803 lappend tags $tag
3804 }
3805 }
3806 return $tags
3807}
3808
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003809# called when we have finished computing the nearby tags
3810proc dispneartags {} {
3811 global selectedline currentid ctext anc_tags desc_tags showneartags
Paul Mackerrasef030b82006-06-04 11:50:38 +10003812 global desc_heads
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003813
3814 if {![info exists selectedline] || !$showneartags} return
3815 set id $currentid
3816 $ctext conf -state normal
Paul Mackerrasef030b82006-06-04 11:50:38 +10003817 if {[info exists desc_heads($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003818 if {[appendrefs branch $desc_heads($id) headids] > 1} {
Paul Mackerrasef030b82006-06-04 11:50:38 +10003819 $ctext insert "branch -2c" "es"
3820 }
3821 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003822 if {[info exists anc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003823 appendrefs follows [taglist $anc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003824 }
3825 if {[info exists desc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003826 appendrefs precedes [taglist $desc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003827 }
3828 $ctext conf -state disabled
3829}
3830
Paul Mackerrasd6982062005-08-06 22:06:06 +10003831proc selectline {l isnew} {
Paul Mackerrasd2610d12005-05-11 00:45:38 +00003832 global canv canv2 canv3 ctext commitinfo selectedline
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003833 global displayorder linehtag linentag linedtag
Paul Mackerras79b2c752006-04-02 20:47:40 +10003834 global canvy0 linespc parentlist childlist
Paul Mackerras7fcceed2006-04-27 19:21:49 +10003835 global currentid sha1entry
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003836 global commentend idtags linknum
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003837 global mergemax numcommits pending_select
Paul Mackerrasef030b82006-06-04 11:50:38 +10003838 global cmitmode desc_tags anc_tags showneartags allcommits desc_heads
Paul Mackerrasd6982062005-08-06 22:06:06 +10003839
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003840 catch {unset pending_select}
Paul Mackerras84ba7342005-06-17 00:12:26 +00003841 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10003842 normalline
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003843 cancel_next_highlight
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003844 if {$l < 0 || $l >= $numcommits} return
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003845 set y [expr {$canvy0 + $l * $linespc}]
Paul Mackerras17386062005-05-18 22:51:00 +00003846 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerras58422152005-05-19 10:56:42 +00003847 set ytop [expr {$y - $linespc - 1}]
3848 set ybot [expr {$y + $linespc + 1}]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003849 set wnow [$canv yview]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003850 set wtop [expr {[lindex $wnow 0] * $ymax}]
3851 set wbot [expr {[lindex $wnow 1] * $ymax}]
Paul Mackerras58422152005-05-19 10:56:42 +00003852 set wh [expr {$wbot - $wtop}]
3853 set newtop $wtop
Paul Mackerras17386062005-05-18 22:51:00 +00003854 if {$ytop < $wtop} {
Paul Mackerras58422152005-05-19 10:56:42 +00003855 if {$ybot < $wtop} {
3856 set newtop [expr {$y - $wh / 2.0}]
3857 } else {
3858 set newtop $ytop
3859 if {$newtop > $wtop - $linespc} {
3860 set newtop [expr {$wtop - $linespc}]
3861 }
Paul Mackerras17386062005-05-18 22:51:00 +00003862 }
Paul Mackerras58422152005-05-19 10:56:42 +00003863 } elseif {$ybot > $wbot} {
3864 if {$ytop > $wbot} {
3865 set newtop [expr {$y - $wh / 2.0}]
3866 } else {
3867 set newtop [expr {$ybot - $wh}]
3868 if {$newtop < $wtop + $linespc} {
3869 set newtop [expr {$wtop + $linespc}]
3870 }
Paul Mackerras17386062005-05-18 22:51:00 +00003871 }
Paul Mackerras58422152005-05-19 10:56:42 +00003872 }
3873 if {$newtop != $wtop} {
3874 if {$newtop < 0} {
3875 set newtop 0
3876 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003877 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003878 drawvisible
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003879 }
Paul Mackerrasd6982062005-08-06 22:06:06 +10003880
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003881 if {![info exists linehtag($l)]} return
3882 $canv delete secsel
3883 set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
3884 -tags secsel -fill [$canv cget -selectbackground]]
3885 $canv lower $t
3886 $canv2 delete secsel
3887 set t [eval $canv2 create rect [$canv2 bbox $linentag($l)] -outline {{}} \
3888 -tags secsel -fill [$canv2 cget -selectbackground]]
3889 $canv2 lower $t
3890 $canv3 delete secsel
3891 set t [eval $canv3 create rect [$canv3 bbox $linedtag($l)] -outline {{}} \
3892 -tags secsel -fill [$canv3 cget -selectbackground]]
3893 $canv3 lower $t
3894
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003895 if {$isnew} {
3896 addtohistory [list selectline $l 0]
Paul Mackerrasd6982062005-08-06 22:06:06 +10003897 }
3898
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003899 set selectedline $l
3900
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003901 set id [lindex $displayorder $l]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00003902 set currentid $id
Paul Mackerras98f350e2005-05-15 05:56:51 +00003903 $sha1entry delete 0 end
3904 $sha1entry insert 0 $id
3905 $sha1entry selection from 0
3906 $sha1entry selection to end
Paul Mackerras164ff272006-05-29 19:50:02 +10003907 rhighlight_sel $id
Paul Mackerras98f350e2005-05-15 05:56:51 +00003908
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003909 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10003910 clear_ctext
Paul Mackerras106288c2005-08-19 23:11:39 +10003911 set linknum 0
Paul Mackerras1db95b02005-05-09 04:08:39 +00003912 set info $commitinfo($id)
Paul Mackerras232475d2005-11-15 10:34:03 +11003913 set date [formatdate [lindex $info 2]]
3914 $ctext insert end "Author: [lindex $info 1] $date\n"
3915 set date [formatdate [lindex $info 4]]
3916 $ctext insert end "Committer: [lindex $info 3] $date\n"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00003917 if {[info exists idtags($id)]} {
3918 $ctext insert end "Tags:"
3919 foreach tag $idtags($id) {
3920 $ctext insert end " $tag"
3921 }
3922 $ctext insert end "\n"
3923 }
Mark Levedahl40b87ff2007-02-01 08:44:46 -05003924
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003925 set headers {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10003926 set olds [lindex $parentlist $l]
3927 if {[llength $olds] > 1} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003928 set np 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10003929 foreach p $olds {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003930 if {$np >= $mergemax} {
3931 set tag mmax
3932 } else {
3933 set tag m$np
3934 }
3935 $ctext insert end "Parent: " $tag
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003936 appendwithlinks [commit_descriptor $p] {}
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003937 incr np
3938 }
3939 } else {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003940 foreach p $olds {
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003941 append headers "Parent: [commit_descriptor $p]"
Linus Torvalds8b192802005-08-07 13:58:56 -07003942 }
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003943 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003944
Paul Mackerras79b2c752006-04-02 20:47:40 +10003945 foreach c [lindex $childlist $l] {
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003946 append headers "Child: [commit_descriptor $c]"
Linus Torvalds8b192802005-08-07 13:58:56 -07003947 }
Paul Mackerrasd6982062005-08-06 22:06:06 +10003948
3949 # make anything that looks like a SHA1 ID be a clickable link
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003950 appendwithlinks $headers {}
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003951 if {$showneartags} {
3952 if {![info exists allcommits]} {
3953 getallcommits
3954 }
Paul Mackerrasef030b82006-06-04 11:50:38 +10003955 $ctext insert end "Branch: "
3956 $ctext mark set branch "end -1c"
3957 $ctext mark gravity branch left
3958 if {[info exists desc_heads($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003959 if {[appendrefs branch $desc_heads($id) headids] > 1} {
Paul Mackerrasef030b82006-06-04 11:50:38 +10003960 # turn "Branch" into "Branches"
3961 $ctext insert "branch -2c" "es"
3962 }
3963 }
3964 $ctext insert end "\nFollows: "
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003965 $ctext mark set follows "end -1c"
3966 $ctext mark gravity follows left
3967 if {[info exists anc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003968 appendrefs follows [taglist $anc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003969 }
3970 $ctext insert end "\nPrecedes: "
3971 $ctext mark set precedes "end -1c"
3972 $ctext mark gravity precedes left
3973 if {[info exists desc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003974 appendrefs precedes [taglist $desc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003975 }
3976 $ctext insert end "\n"
3977 }
3978 $ctext insert end "\n"
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003979 appendwithlinks [lindex $info 5] {comment}
Paul Mackerrasd6982062005-08-06 22:06:06 +10003980
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003981 $ctext tag delete Comments
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003982 $ctext tag remove found 1.0 end
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003983 $ctext conf -state disabled
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003984 set commentend [$ctext index "end - 1c"]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003985
Paul Mackerras7fcceed2006-04-27 19:21:49 +10003986 init_flist "Comments"
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10003987 if {$cmitmode eq "tree"} {
3988 gettree $id
3989 } elseif {[llength $olds] <= 1} {
Paul Mackerrasd3272442005-11-28 20:41:56 +11003990 startdiff $id
Paul Mackerras7b5ff7e2006-03-30 20:50:40 +11003991 } else {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003992 mergediff $id $l
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003993 }
3994}
3995
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10003996proc selfirstline {} {
3997 unmarkmatches
3998 selectline 0 1
3999}
4000
4001proc sellastline {} {
4002 global numcommits
4003 unmarkmatches
4004 set l [expr {$numcommits - 1}]
4005 selectline $l 1
4006}
4007
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004008proc selnextline {dir} {
4009 global selectedline
4010 if {![info exists selectedline]} return
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08004011 set l [expr {$selectedline + $dir}]
Paul Mackerras98f350e2005-05-15 05:56:51 +00004012 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10004013 selectline $l 1
4014}
4015
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004016proc selnextpage {dir} {
4017 global canv linespc selectedline numcommits
4018
4019 set lpp [expr {([winfo height $canv] - 2) / $linespc}]
4020 if {$lpp < 1} {
4021 set lpp 1
4022 }
4023 allcanvs yview scroll [expr {$dir * $lpp}] units
Paul Mackerrase72ee5e2006-05-20 09:58:49 +10004024 drawvisible
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004025 if {![info exists selectedline]} return
4026 set l [expr {$selectedline + $dir * $lpp}]
4027 if {$l < 0} {
4028 set l 0
4029 } elseif {$l >= $numcommits} {
4030 set l [expr $numcommits - 1]
4031 }
4032 unmarkmatches
Mark Levedahl40b87ff2007-02-01 08:44:46 -05004033 selectline $l 1
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004034}
4035
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004036proc unselectline {} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004037 global selectedline currentid
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004038
4039 catch {unset selectedline}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004040 catch {unset currentid}
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004041 allcanvs delete secsel
Paul Mackerras164ff272006-05-29 19:50:02 +10004042 rhighlight_none
Paul Mackerras4e7d6772006-05-30 21:33:07 +10004043 cancel_next_highlight
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004044}
4045
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004046proc reselectline {} {
4047 global selectedline
4048
4049 if {[info exists selectedline]} {
4050 selectline $selectedline 0
4051 }
4052}
4053
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004054proc addtohistory {cmd} {
Paul Mackerras2516dae2006-04-21 10:35:31 +10004055 global history historyindex curview
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004056
Paul Mackerras2516dae2006-04-21 10:35:31 +10004057 set elt [list $curview $cmd]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004058 if {$historyindex > 0
Paul Mackerras2516dae2006-04-21 10:35:31 +10004059 && [lindex $history [expr {$historyindex - 1}]] == $elt} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004060 return
4061 }
4062
4063 if {$historyindex < [llength $history]} {
Paul Mackerras2516dae2006-04-21 10:35:31 +10004064 set history [lreplace $history $historyindex end $elt]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004065 } else {
Paul Mackerras2516dae2006-04-21 10:35:31 +10004066 lappend history $elt
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004067 }
4068 incr historyindex
4069 if {$historyindex > 1} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004070 .tf.bar.leftbut conf -state normal
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004071 } else {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004072 .tf.bar.leftbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004073 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004074 .tf.bar.rightbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004075}
4076
Paul Mackerras2516dae2006-04-21 10:35:31 +10004077proc godo {elt} {
4078 global curview
4079
4080 set view [lindex $elt 0]
4081 set cmd [lindex $elt 1]
4082 if {$curview != $view} {
4083 showview $view
4084 }
4085 eval $cmd
4086}
4087
Paul Mackerrasd6982062005-08-06 22:06:06 +10004088proc goback {} {
4089 global history historyindex
4090
4091 if {$historyindex > 1} {
4092 incr historyindex -1
Paul Mackerras2516dae2006-04-21 10:35:31 +10004093 godo [lindex $history [expr {$historyindex - 1}]]
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004094 .tf.bar.rightbut conf -state normal
Paul Mackerrasd6982062005-08-06 22:06:06 +10004095 }
4096 if {$historyindex <= 1} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004097 .tf.bar.leftbut conf -state disabled
Paul Mackerrasd6982062005-08-06 22:06:06 +10004098 }
4099}
4100
4101proc goforw {} {
4102 global history historyindex
4103
4104 if {$historyindex < [llength $history]} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004105 set cmd [lindex $history $historyindex]
Paul Mackerrasd6982062005-08-06 22:06:06 +10004106 incr historyindex
Paul Mackerras2516dae2006-04-21 10:35:31 +10004107 godo $cmd
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004108 .tf.bar.leftbut conf -state normal
Paul Mackerrasd6982062005-08-06 22:06:06 +10004109 }
4110 if {$historyindex >= [llength $history]} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004111 .tf.bar.rightbut conf -state disabled
Paul Mackerrasd6982062005-08-06 22:06:06 +10004112 }
Paul Mackerras5ad588d2005-05-10 01:02:55 +00004113}
4114
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004115proc gettree {id} {
4116 global treefilelist treeidlist diffids diffmergeid treepending
4117
4118 set diffids $id
4119 catch {unset diffmergeid}
4120 if {![info exists treefilelist($id)]} {
4121 if {![info exists treepending]} {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004122 if {[catch {set gtf [open [concat | git ls-tree -r $id] r]}]} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004123 return
4124 }
4125 set treepending $id
4126 set treefilelist($id) {}
4127 set treeidlist($id) {}
4128 fconfigure $gtf -blocking 0
4129 fileevent $gtf readable [list gettreeline $gtf $id]
4130 }
4131 } else {
4132 setfilelist $id
4133 }
4134}
4135
4136proc gettreeline {gtf id} {
4137 global treefilelist treeidlist treepending cmitmode diffids
4138
4139 while {[gets $gtf line] >= 0} {
4140 if {[lindex $line 1] ne "blob"} continue
4141 set sha1 [lindex $line 2]
4142 set fname [lindex $line 3]
4143 lappend treefilelist($id) $fname
4144 lappend treeidlist($id) $sha1
4145 }
4146 if {![eof $gtf]} return
4147 close $gtf
4148 unset treepending
4149 if {$cmitmode ne "tree"} {
4150 if {![info exists diffmergeid]} {
4151 gettreediffs $diffids
4152 }
4153 } elseif {$id ne $diffids} {
4154 gettree $diffids
4155 } else {
4156 setfilelist $id
4157 }
4158}
4159
4160proc showfile {f} {
4161 global treefilelist treeidlist diffids
4162 global ctext commentend
4163
4164 set i [lsearch -exact $treefilelist($diffids) $f]
4165 if {$i < 0} {
4166 puts "oops, $f not in list for id $diffids"
4167 return
4168 }
4169 set blob [lindex $treeidlist($diffids) $i]
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004170 if {[catch {set bf [open [concat | git cat-file blob $blob] r]} err]} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004171 puts "oops, error reading blob $blob: $err"
4172 return
4173 }
4174 fconfigure $bf -blocking 0
4175 fileevent $bf readable [list getblobline $bf $diffids]
4176 $ctext config -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004177 clear_ctext $commentend
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004178 $ctext insert end "\n"
4179 $ctext insert end "$f\n" filesep
4180 $ctext config -state disabled
4181 $ctext yview $commentend
4182}
4183
4184proc getblobline {bf id} {
4185 global diffids cmitmode ctext
4186
4187 if {$id ne $diffids || $cmitmode ne "tree"} {
4188 catch {close $bf}
4189 return
4190 }
4191 $ctext config -state normal
4192 while {[gets $bf line] >= 0} {
4193 $ctext insert end "$line\n"
4194 }
4195 if {[eof $bf]} {
4196 # delete last newline
4197 $ctext delete "end - 2c" "end - 1c"
4198 close $bf
4199 }
4200 $ctext config -state disabled
4201}
4202
Paul Mackerras79b2c752006-04-02 20:47:40 +10004203proc mergediff {id l} {
4204 global diffmergeid diffopts mdifffd
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004205 global diffids
Paul Mackerras79b2c752006-04-02 20:47:40 +10004206 global parentlist
Paul Mackerrase2ed4322005-07-17 03:39:44 -04004207
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004208 set diffmergeid $id
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004209 set diffids $id
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004210 # this doesn't seem to actually affect anything...
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004211 set env(GIT_DIFF_OPTS) $diffopts
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004212 set cmd [concat | git diff-tree --no-commit-id --cc $id]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004213 if {[catch {set mdf [open $cmd r]} err]} {
4214 error_popup "Error getting merge diffs: $err"
4215 return
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004216 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004217 fconfigure $mdf -blocking 0
4218 set mdifffd($id) $mdf
Paul Mackerras79b2c752006-04-02 20:47:40 +10004219 set np [llength [lindex $parentlist $l]]
4220 fileevent $mdf readable [list getmergediffline $mdf $id $np]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004221 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004222}
4223
Paul Mackerras79b2c752006-04-02 20:47:40 +10004224proc getmergediffline {mdf id np} {
4225 global diffmergeid ctext cflist nextupdate mergemax
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004226 global difffilestart mdifffd
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004227
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004228 set n [gets $mdf line]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004229 if {$n < 0} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004230 if {[eof $mdf]} {
4231 close $mdf
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004232 }
4233 return
4234 }
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004235 if {![info exists diffmergeid] || $id != $diffmergeid
4236 || $mdf != $mdifffd($id)} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004237 return
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004238 }
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004239 $ctext conf -state normal
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004240 if {[regexp {^diff --cc (.*)} $line match fname]} {
4241 # start of a new file
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004242 $ctext insert end "\n"
4243 set here [$ctext index "end - 1c"]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004244 lappend difffilestart $here
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004245 add_flist [list $fname]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004246 set l [expr {(78 - [string length $fname]) / 2}]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004247 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004248 $ctext insert end "$pad $fname $pad\n" filesep
4249 } elseif {[regexp {^@@} $line]} {
4250 $ctext insert end "$line\n" hunksep
4251 } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
4252 # do nothing
4253 } else {
4254 # parse the prefix - one ' ', '-' or '+' for each parent
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004255 set spaces {}
4256 set minuses {}
4257 set pluses {}
4258 set isbad 0
4259 for {set j 0} {$j < $np} {incr j} {
4260 set c [string range $line $j $j]
4261 if {$c == " "} {
4262 lappend spaces $j
4263 } elseif {$c == "-"} {
4264 lappend minuses $j
4265 } elseif {$c == "+"} {
4266 lappend pluses $j
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004267 } else {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004268 set isbad 1
4269 break
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004270 }
4271 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004272 set tags {}
4273 set num {}
4274 if {!$isbad && $minuses ne {} && $pluses eq {}} {
4275 # line doesn't appear in result, parents in $minuses have the line
4276 set num [lindex $minuses 0]
4277 } elseif {!$isbad && $pluses ne {} && $minuses eq {}} {
4278 # line appears in result, parents in $pluses don't have the line
4279 lappend tags mresult
4280 set num [lindex $spaces 0]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004281 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004282 if {$num ne {}} {
4283 if {$num >= $mergemax} {
4284 set num "max"
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004285 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004286 lappend tags m$num
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004287 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004288 $ctext insert end "$line\n" $tags
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004289 }
4290 $ctext conf -state disabled
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004291 if {[clock clicks -milliseconds] >= $nextupdate} {
4292 incr nextupdate 100
4293 fileevent $mdf readable {}
4294 update
Paul Mackerrasc5a4c4d2006-04-06 10:20:03 +10004295 fileevent $mdf readable [list getmergediffline $mdf $id $np]
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05004296 }
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05004297}
4298
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004299proc startdiff {ids} {
4300 global treediffs diffids treepending diffmergeid
4301
4302 set diffids $ids
4303 catch {unset diffmergeid}
4304 if {![info exists treediffs($ids)]} {
4305 if {![info exists treepending]} {
4306 gettreediffs $ids
4307 }
4308 } else {
4309 addtocflist $ids
4310 }
4311}
4312
4313proc addtocflist {ids} {
4314 global treediffs cflist
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004315 add_flist $treediffs($ids)
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004316 getblobdiffs $ids
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004317}
4318
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004319proc gettreediffs {ids} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10004320 global treediff treepending
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004321 set treepending $ids
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004322 set treediff {}
Paul Mackerras418c4c72006-02-07 09:10:18 +11004323 if {[catch \
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004324 {set gdtf [open [concat | git diff-tree --no-commit-id -r $ids] r]} \
Paul Mackerras418c4c72006-02-07 09:10:18 +11004325 ]} return
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004326 fconfigure $gdtf -blocking 0
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004327 fileevent $gdtf readable [list gettreediffline $gdtf $ids]
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004328}
4329
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004330proc gettreediffline {gdtf ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004331 global treediff treediffs treepending diffids diffmergeid
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004332 global cmitmode
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004333
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004334 set n [gets $gdtf line]
4335 if {$n < 0} {
4336 if {![eof $gdtf]} return
4337 close $gdtf
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004338 set treediffs($ids) $treediff
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004339 unset treepending
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004340 if {$cmitmode eq "tree"} {
4341 gettree $diffids
4342 } elseif {$ids != $diffids} {
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004343 if {![info exists diffmergeid]} {
4344 gettreediffs $diffids
Paul Mackerrasb74fd572005-07-16 07:46:13 -04004345 }
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004346 } else {
4347 addtocflist $ids
Paul Mackerrasb74fd572005-07-16 07:46:13 -04004348 }
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004349 return
4350 }
Paul Mackerrasd4e95cb2005-06-01 00:02:13 +00004351 set file [lindex $line 5]
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004352 lappend treediff $file
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004353}
4354
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004355proc getblobdiffs {ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004356 global diffopts blobdifffd diffids env curdifftag curtagstart
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004357 global nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004358
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004359 set env(GIT_DIFF_OPTS) $diffopts
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004360 set cmd [concat | git diff-tree --no-commit-id -r -p -C $ids]
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004361 if {[catch {set bdf [open $cmd r]} err]} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004362 puts "error getting diffs: $err"
4363 return
4364 }
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004365 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004366 fconfigure $bdf -blocking 0
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004367 set blobdifffd($ids) $bdf
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004368 set curdifftag Comments
4369 set curtagstart 0.0
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004370 fileevent $bdf readable [list getblobdiffline $bdf $diffids]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004371 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004372}
4373
Paul Mackerras89b11d32006-05-02 19:55:31 +10004374proc setinlist {var i val} {
4375 global $var
4376
4377 while {[llength [set $var]] < $i} {
4378 lappend $var {}
4379 }
4380 if {[llength [set $var]] == $i} {
4381 lappend $var $val
4382 } else {
4383 lset $var $i $val
4384 }
4385}
4386
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004387proc getblobdiffline {bdf ids} {
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004388 global diffids blobdifffd ctext curdifftag curtagstart
Paul Mackerras7eab2932005-07-20 12:25:54 -04004389 global diffnexthead diffnextnote difffilestart
4390 global nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004391
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004392 set n [gets $bdf line]
4393 if {$n < 0} {
4394 if {[eof $bdf]} {
4395 close $bdf
Paul Mackerrase2ed4322005-07-17 03:39:44 -04004396 if {$ids == $diffids && $bdf == $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004397 $ctext tag add $curdifftag $curtagstart end
4398 }
4399 }
4400 return
4401 }
Paul Mackerrase2ed4322005-07-17 03:39:44 -04004402 if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004403 return
4404 }
4405 $ctext conf -state normal
Paul Mackerras7eab2932005-07-20 12:25:54 -04004406 if {[regexp {^diff --git a/(.*) b/(.*)} $line match fname newname]} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004407 # start of a new file
4408 $ctext insert end "\n"
4409 $ctext tag add $curdifftag $curtagstart end
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004410 set here [$ctext index "end - 1c"]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004411 set curtagstart $here
4412 set header $newname
Paul Mackerras89b11d32006-05-02 19:55:31 +10004413 set i [lsearch -exact $treediffs($ids) $fname]
4414 if {$i >= 0} {
4415 setinlist difffilestart $i $here
4416 }
4417 if {$newname ne $fname} {
4418 set i [lsearch -exact $treediffs($ids) $newname]
4419 if {$i >= 0} {
4420 setinlist difffilestart $i $here
4421 }
Paul Mackerras7eab2932005-07-20 12:25:54 -04004422 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004423 set curdifftag "f:$fname"
4424 $ctext tag delete $curdifftag
Paul Mackerras58422152005-05-19 10:56:42 +00004425 set l [expr {(78 - [string length $header]) / 2}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004426 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerras58422152005-05-19 10:56:42 +00004427 $ctext insert end "$pad $header $pad\n" filesep
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004428 set diffinhdr 1
Paul Mackerrasb06bc2a2006-03-08 09:15:32 +11004429 } elseif {$diffinhdr && [string compare -length 3 $line "---"] == 0} {
4430 # do nothing
4431 } elseif {$diffinhdr && [string compare -length 3 $line "+++"] == 0} {
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004432 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004433 } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
4434 $line match f1l f1c f2l f2c rest]} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11004435 $ctext insert end "$line\n" hunksep
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004436 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004437 } else {
4438 set x [string range $line 0 0]
4439 if {$x == "-" || $x == "+"} {
4440 set tag [expr {$x == "+"}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004441 $ctext insert end "$line\n" d$tag
4442 } elseif {$x == " "} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004443 $ctext insert end "$line\n"
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004444 } elseif {$diffinhdr || $x == "\\"} {
Paul Mackerras58422152005-05-19 10:56:42 +00004445 # e.g. "\ No newline at end of file"
4446 $ctext insert end "$line\n" filesep
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004447 } else {
4448 # Something else we don't recognize
4449 if {$curdifftag != "Comments"} {
4450 $ctext insert end "\n"
4451 $ctext tag add $curdifftag $curtagstart end
4452 set curtagstart [$ctext index "end - 1c"]
4453 set curdifftag Comments
4454 }
4455 $ctext insert end "$line\n" filesep
4456 }
4457 }
4458 $ctext conf -state disabled
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004459 if {[clock clicks -milliseconds] >= $nextupdate} {
4460 incr nextupdate 100
4461 fileevent $bdf readable {}
4462 update
4463 fileevent $bdf readable "getblobdiffline $bdf {$ids}"
4464 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004465}
4466
OGAWA Hirofumi67c22872006-09-27 12:32:19 +09004467proc prevfile {} {
4468 global difffilestart ctext
4469 set prev [lindex $difffilestart 0]
4470 set here [$ctext index @0,0]
4471 foreach loc $difffilestart {
4472 if {[$ctext compare $loc >= $here]} {
4473 $ctext yview $prev
4474 return
4475 }
4476 set prev $loc
4477 }
4478 $ctext yview $prev
4479}
4480
Paul Mackerras39ad8572005-05-19 12:35:53 +00004481proc nextfile {} {
4482 global difffilestart ctext
4483 set here [$ctext index @0,0]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004484 foreach loc $difffilestart {
4485 if {[$ctext compare $loc > $here]} {
4486 $ctext yview $loc
OGAWA Hirofumi67c22872006-09-27 12:32:19 +09004487 return
Paul Mackerras39ad8572005-05-19 12:35:53 +00004488 }
4489 }
Paul Mackerras1db95b02005-05-09 04:08:39 +00004490}
4491
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004492proc clear_ctext {{first 1.0}} {
4493 global ctext smarktop smarkbot
4494
Paul Mackerras1902c272006-05-25 21:25:13 +10004495 set l [lindex [split $first .] 0]
4496 if {![info exists smarktop] || [$ctext compare $first < $smarktop.0]} {
4497 set smarktop $l
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004498 }
Paul Mackerras1902c272006-05-25 21:25:13 +10004499 if {![info exists smarkbot] || [$ctext compare $first < $smarkbot.0]} {
4500 set smarkbot $l
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004501 }
4502 $ctext delete $first end
4503}
4504
4505proc incrsearch {name ix op} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004506 global ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004507
4508 $ctext tag remove found 1.0 end
Paul Mackerras1902c272006-05-25 21:25:13 +10004509 if {[catch {$ctext index anchor}]} {
4510 # no anchor set, use start of selection, or of visible area
4511 set sel [$ctext tag ranges sel]
4512 if {$sel ne {}} {
4513 $ctext mark set anchor [lindex $sel 0]
4514 } elseif {$searchdirn eq "-forwards"} {
4515 $ctext mark set anchor @0,0
4516 } else {
4517 $ctext mark set anchor @0,[winfo height $ctext]
4518 }
4519 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004520 if {$searchstring ne {}} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004521 set here [$ctext search $searchdirn -- $searchstring anchor]
4522 if {$here ne {}} {
4523 $ctext see $here
4524 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004525 searchmarkvisible 1
4526 }
4527}
4528
4529proc dosearch {} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004530 global sstring ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004531
4532 focus $sstring
4533 $sstring icursor end
Paul Mackerras1902c272006-05-25 21:25:13 +10004534 set searchdirn -forwards
4535 if {$searchstring ne {}} {
4536 set sel [$ctext tag ranges sel]
4537 if {$sel ne {}} {
4538 set start "[lindex $sel 0] + 1c"
4539 } elseif {[catch {set start [$ctext index anchor]}]} {
4540 set start "@0,0"
4541 }
4542 set match [$ctext search -count mlen -- $searchstring $start]
4543 $ctext tag remove sel 1.0 end
4544 if {$match eq {}} {
4545 bell
4546 return
4547 }
4548 $ctext see $match
4549 set mend "$match + $mlen c"
4550 $ctext tag add sel $match $mend
4551 $ctext mark unset anchor
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004552 }
Paul Mackerras1902c272006-05-25 21:25:13 +10004553}
4554
4555proc dosearchback {} {
4556 global sstring ctext searchstring searchdirn
4557
4558 focus $sstring
4559 $sstring icursor end
4560 set searchdirn -backwards
4561 if {$searchstring ne {}} {
4562 set sel [$ctext tag ranges sel]
4563 if {$sel ne {}} {
4564 set start [lindex $sel 0]
4565 } elseif {[catch {set start [$ctext index anchor]}]} {
4566 set start @0,[winfo height $ctext]
4567 }
4568 set match [$ctext search -backwards -count ml -- $searchstring $start]
4569 $ctext tag remove sel 1.0 end
4570 if {$match eq {}} {
4571 bell
4572 return
4573 }
4574 $ctext see $match
4575 set mend "$match + $ml c"
4576 $ctext tag add sel $match $mend
4577 $ctext mark unset anchor
4578 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004579}
4580
4581proc searchmark {first last} {
4582 global ctext searchstring
4583
4584 set mend $first.0
4585 while {1} {
4586 set match [$ctext search -count mlen -- $searchstring $mend $last.end]
4587 if {$match eq {}} break
4588 set mend "$match + $mlen c"
4589 $ctext tag add found $match $mend
4590 }
4591}
4592
4593proc searchmarkvisible {doall} {
4594 global ctext smarktop smarkbot
4595
4596 set topline [lindex [split [$ctext index @0,0] .] 0]
4597 set botline [lindex [split [$ctext index @0,[winfo height $ctext]] .] 0]
4598 if {$doall || $botline < $smarktop || $topline > $smarkbot} {
4599 # no overlap with previous
4600 searchmark $topline $botline
4601 set smarktop $topline
4602 set smarkbot $botline
4603 } else {
4604 if {$topline < $smarktop} {
4605 searchmark $topline [expr {$smarktop-1}]
4606 set smarktop $topline
4607 }
4608 if {$botline > $smarkbot} {
4609 searchmark [expr {$smarkbot+1}] $botline
4610 set smarkbot $botline
4611 }
4612 }
4613}
4614
4615proc scrolltext {f0 f1} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004616 global searchstring
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004617
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004618 .bleft.sb set $f0 $f1
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004619 if {$searchstring ne {}} {
4620 searchmarkvisible 0
4621 }
4622}
4623
Paul Mackerras1d10f362005-05-15 12:55:47 +00004624proc setcoords {} {
4625 global linespc charspc canvx0 canvy0 mainfont
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10004626 global xspc1 xspc2 lthickness
Paul Mackerras8d858d12005-08-05 09:52:16 +10004627
Paul Mackerras1d10f362005-05-15 12:55:47 +00004628 set linespc [font metrics $mainfont -linespace]
4629 set charspc [font measure $mainfont "m"]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004630 set canvy0 [expr {int(3 + 0.5 * $linespc)}]
4631 set canvx0 [expr {int(3 + 0.5 * $linespc)}]
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10004632 set lthickness [expr {int($linespc / 9) + 1}]
Paul Mackerras8d858d12005-08-05 09:52:16 +10004633 set xspc1(0) $linespc
4634 set xspc2 $linespc
Paul Mackerras9a40c502005-05-12 23:46:16 +00004635}
Paul Mackerras1db95b02005-05-09 04:08:39 +00004636
Paul Mackerras1d10f362005-05-15 12:55:47 +00004637proc redisplay {} {
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11004638 global canv
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004639 global selectedline
4640
4641 set ymax [lindex [$canv cget -scrollregion] 3]
4642 if {$ymax eq {} || $ymax == 0} return
4643 set span [$canv yview]
4644 clear_display
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11004645 setcanvscroll
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004646 allcanvs yview moveto [lindex $span 0]
4647 drawvisible
4648 if {[info exists selectedline]} {
4649 selectline $selectedline 0
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10004650 allcanvs yview moveto [lindex $span 0]
Paul Mackerras1db95b02005-05-09 04:08:39 +00004651 }
4652}
Paul Mackerras1d10f362005-05-15 12:55:47 +00004653
4654proc incrfont {inc} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004655 global mainfont textfont ctext canv phase
Paul Mackerrascfb45632005-05-31 12:14:42 +00004656 global stopped entries
Paul Mackerras1d10f362005-05-15 12:55:47 +00004657 unmarkmatches
4658 set mainfont [lreplace $mainfont 1 1 [expr {[lindex $mainfont 1] + $inc}]]
Paul Mackerras1d10f362005-05-15 12:55:47 +00004659 set textfont [lreplace $textfont 1 1 [expr {[lindex $textfont 1] + $inc}]]
4660 setcoords
4661 $ctext conf -font $textfont
4662 $ctext tag conf filesep -font [concat $textfont bold]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004663 foreach e $entries {
4664 $e conf -font $mainfont
4665 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10004666 if {$phase eq "getcommits"} {
Paul Mackerras1d10f362005-05-15 12:55:47 +00004667 $canv itemconf textitems -font $mainfont
4668 }
4669 redisplay
Paul Mackerras1db95b02005-05-09 04:08:39 +00004670}
Paul Mackerras1d10f362005-05-15 12:55:47 +00004671
Paul Mackerrasee3dc722005-06-25 16:37:13 +10004672proc clearsha1 {} {
4673 global sha1entry sha1string
4674 if {[string length $sha1string] == 40} {
4675 $sha1entry delete 0 end
4676 }
4677}
4678
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004679proc sha1change {n1 n2 op} {
4680 global sha1string currentid sha1but
4681 if {$sha1string == {}
4682 || ([info exists currentid] && $sha1string == $currentid)} {
4683 set state disabled
4684 } else {
4685 set state normal
4686 }
4687 if {[$sha1but cget -state] == $state} return
4688 if {$state == "normal"} {
4689 $sha1but conf -state normal -relief raised -text "Goto: "
4690 } else {
4691 $sha1but conf -state disabled -relief flat -text "SHA1 ID: "
4692 }
4693}
4694
4695proc gotocommit {} {
Stephen Rothwelle1007122006-03-30 16:13:12 +11004696 global sha1string currentid commitrow tagids headids
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004697 global displayorder numcommits curview
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004698
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004699 if {$sha1string == {}
4700 || ([info exists currentid] && $sha1string == $currentid)} return
4701 if {[info exists tagids($sha1string)]} {
4702 set id $tagids($sha1string)
Stephen Rothwelle1007122006-03-30 16:13:12 +11004703 } elseif {[info exists headids($sha1string)]} {
4704 set id $headids($sha1string)
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004705 } else {
4706 set id [string tolower $sha1string]
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004707 if {[regexp {^[0-9a-f]{4,39}$} $id]} {
4708 set matches {}
Paul Mackerras8ed16482006-03-02 22:56:44 +11004709 foreach i $displayorder {
4710 if {[string match $id* $i]} {
4711 lappend matches $i
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004712 }
4713 }
4714 if {$matches ne {}} {
4715 if {[llength $matches] > 1} {
4716 error_popup "Short SHA1 id $id is ambiguous"
4717 return
4718 }
4719 set id [lindex $matches 0]
4720 }
4721 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004722 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004723 if {[info exists commitrow($curview,$id)]} {
4724 selectline $commitrow($curview,$id) 1
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004725 return
4726 }
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004727 if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004728 set type "SHA1 id"
4729 } else {
Stephen Rothwelle1007122006-03-30 16:13:12 +11004730 set type "Tag/Head"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004731 }
4732 error_popup "$type $sha1string is not known"
4733}
4734
Paul Mackerras84ba7342005-06-17 00:12:26 +00004735proc lineenter {x y id} {
4736 global hoverx hovery hoverid hovertimer
4737 global commitinfo canv
4738
Paul Mackerras8ed16482006-03-02 22:56:44 +11004739 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerras84ba7342005-06-17 00:12:26 +00004740 set hoverx $x
4741 set hovery $y
4742 set hoverid $id
4743 if {[info exists hovertimer]} {
4744 after cancel $hovertimer
4745 }
4746 set hovertimer [after 500 linehover]
4747 $canv delete hover
4748}
4749
4750proc linemotion {x y id} {
4751 global hoverx hovery hoverid hovertimer
4752
4753 if {[info exists hoverid] && $id == $hoverid} {
4754 set hoverx $x
4755 set hovery $y
4756 if {[info exists hovertimer]} {
4757 after cancel $hovertimer
4758 }
4759 set hovertimer [after 500 linehover]
4760 }
4761}
4762
4763proc lineleave {id} {
4764 global hoverid hovertimer canv
4765
4766 if {[info exists hoverid] && $id == $hoverid} {
4767 $canv delete hover
4768 if {[info exists hovertimer]} {
4769 after cancel $hovertimer
4770 unset hovertimer
4771 }
4772 unset hoverid
4773 }
4774}
4775
4776proc linehover {} {
4777 global hoverx hovery hoverid hovertimer
4778 global canv linespc lthickness
4779 global commitinfo mainfont
4780
4781 set text [lindex $commitinfo($hoverid) 0]
4782 set ymax [lindex [$canv cget -scrollregion] 3]
4783 if {$ymax == {}} return
4784 set yfrac [lindex [$canv yview] 0]
4785 set x [expr {$hoverx + 2 * $linespc}]
4786 set y [expr {$hovery + $yfrac * $ymax - $linespc / 2}]
4787 set x0 [expr {$x - 2 * $lthickness}]
4788 set y0 [expr {$y - 2 * $lthickness}]
4789 set x1 [expr {$x + [font measure $mainfont $text] + 2 * $lthickness}]
4790 set y1 [expr {$y + $linespc + 2 * $lthickness}]
4791 set t [$canv create rectangle $x0 $y0 $x1 $y1 \
4792 -fill \#ffff80 -outline black -width 1 -tags hover]
4793 $canv raise $t
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10004794 set t [$canv create text $x $y -anchor nw -text $text -tags hover \
4795 -font $mainfont]
Paul Mackerras84ba7342005-06-17 00:12:26 +00004796 $canv raise $t
4797}
4798
Paul Mackerras9843c302005-08-30 10:57:11 +10004799proc clickisonarrow {id y} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004800 global lthickness
Paul Mackerras9843c302005-08-30 10:57:11 +10004801
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004802 set ranges [rowranges $id]
Paul Mackerras9843c302005-08-30 10:57:11 +10004803 set thresh [expr {2 * $lthickness + 6}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004804 set n [expr {[llength $ranges] - 1}]
Paul Mackerrasf6342482006-02-28 10:02:03 +11004805 for {set i 1} {$i < $n} {incr i} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004806 set row [lindex $ranges $i]
Paul Mackerrasf6342482006-02-28 10:02:03 +11004807 if {abs([yc $row] - $y) < $thresh} {
4808 return $i
Paul Mackerras9843c302005-08-30 10:57:11 +10004809 }
4810 }
4811 return {}
4812}
4813
Paul Mackerrasf6342482006-02-28 10:02:03 +11004814proc arrowjump {id n y} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004815 global canv
Paul Mackerras9843c302005-08-30 10:57:11 +10004816
Paul Mackerrasf6342482006-02-28 10:02:03 +11004817 # 1 <-> 2, 3 <-> 4, etc...
4818 set n [expr {(($n - 1) ^ 1) + 1}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004819 set row [lindex [rowranges $id] $n]
Paul Mackerrasf6342482006-02-28 10:02:03 +11004820 set yt [yc $row]
Paul Mackerras9843c302005-08-30 10:57:11 +10004821 set ymax [lindex [$canv cget -scrollregion] 3]
4822 if {$ymax eq {} || $ymax <= 0} return
4823 set view [$canv yview]
4824 set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
4825 set yfrac [expr {$yt / $ymax - $yspan / 2}]
4826 if {$yfrac < 0} {
4827 set yfrac 0
4828 }
Paul Mackerrasf6342482006-02-28 10:02:03 +11004829 allcanvs yview moveto $yfrac
Paul Mackerras9843c302005-08-30 10:57:11 +10004830}
4831
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004832proc lineclick {x y id isnew} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004833 global ctext commitinfo children canv thickerline curview
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004834
Paul Mackerras8ed16482006-03-02 22:56:44 +11004835 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004836 unmarkmatches
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004837 unselectline
Paul Mackerras9843c302005-08-30 10:57:11 +10004838 normalline
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004839 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10004840 # draw this line thicker than normal
Paul Mackerras9843c302005-08-30 10:57:11 +10004841 set thickerline $id
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004842 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10004843 if {$isnew} {
4844 set ymax [lindex [$canv cget -scrollregion] 3]
4845 if {$ymax eq {}} return
4846 set yfrac [lindex [$canv yview] 0]
4847 set y [expr {$y + $yfrac * $ymax}]
4848 }
4849 set dirn [clickisonarrow $id $y]
4850 if {$dirn ne {}} {
4851 arrowjump $id $dirn $y
4852 return
4853 }
4854
4855 if {$isnew} {
4856 addtohistory [list lineclick $x $y $id 0]
4857 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004858 # fill the details pane with info about this line
4859 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004860 clear_ctext
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004861 $ctext tag conf link -foreground blue -underline 1
4862 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
4863 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
4864 $ctext insert end "Parent:\t"
4865 $ctext insert end $id [list link link0]
4866 $ctext tag bind link0 <1> [list selbyid $id]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004867 set info $commitinfo($id)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004868 $ctext insert end "\n\t[lindex $info 0]\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004869 $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
Paul Mackerras232475d2005-11-15 10:34:03 +11004870 set date [formatdate [lindex $info 2]]
4871 $ctext insert end "\tDate:\t$date\n"
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004872 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 20:47:40 +10004873 if {$kids ne {}} {
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004874 $ctext insert end "\nChildren:"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004875 set i 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10004876 foreach child $kids {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004877 incr i
Paul Mackerras8ed16482006-03-02 22:56:44 +11004878 if {![info exists commitinfo($child)] && ![getcommit $child]} continue
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004879 set info $commitinfo($child)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004880 $ctext insert end "\n\t"
4881 $ctext insert end $child [list link link$i]
4882 $ctext tag bind link$i <1> [list selbyid $child]
4883 $ctext insert end "\n\t[lindex $info 0]"
4884 $ctext insert end "\n\tAuthor:\t[lindex $info 1]"
Paul Mackerras232475d2005-11-15 10:34:03 +11004885 set date [formatdate [lindex $info 2]]
4886 $ctext insert end "\n\tDate:\t$date\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004887 }
4888 }
4889 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004890 init_flist {}
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004891}
4892
Paul Mackerras9843c302005-08-30 10:57:11 +10004893proc normalline {} {
4894 global thickerline
4895 if {[info exists thickerline]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004896 set id $thickerline
Paul Mackerras9843c302005-08-30 10:57:11 +10004897 unset thickerline
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004898 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10004899 }
4900}
4901
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004902proc selbyid {id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004903 global commitrow curview
4904 if {[info exists commitrow($curview,$id)]} {
4905 selectline $commitrow($curview,$id) 1
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004906 }
4907}
4908
4909proc mstime {} {
4910 global startmstime
4911 if {![info exists startmstime]} {
4912 set startmstime [clock clicks -milliseconds]
4913 }
4914 return [format "%.3f" [expr {([clock click -milliseconds] - $startmstime) / 1000.0}]]
4915}
4916
4917proc rowmenu {x y id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004918 global rowctxmenu commitrow selectedline rowmenuid curview
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004919
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004920 if {![info exists selectedline]
4921 || $commitrow($curview,$id) eq $selectedline} {
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004922 set state disabled
4923 } else {
4924 set state normal
4925 }
Paul Mackerras3cd204e2006-11-23 21:06:16 +11004926 $rowctxmenu entryconfigure "Diff this*" -state $state
4927 $rowctxmenu entryconfigure "Diff selected*" -state $state
4928 $rowctxmenu entryconfigure "Make patch" -state $state
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004929 set rowmenuid $id
4930 tk_popup $rowctxmenu $x $y
4931}
4932
4933proc diffvssel {dirn} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004934 global rowmenuid selectedline displayorder
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004935
4936 if {![info exists selectedline]} return
4937 if {$dirn} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004938 set oldid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004939 set newid $rowmenuid
4940 } else {
4941 set oldid $rowmenuid
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004942 set newid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004943 }
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004944 addtohistory [list doseldiff $oldid $newid]
4945 doseldiff $oldid $newid
4946}
4947
4948proc doseldiff {oldid newid} {
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004949 global ctext
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004950 global commitinfo
4951
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004952 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004953 clear_ctext
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004954 init_flist "Top"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004955 $ctext insert end "From "
4956 $ctext tag conf link -foreground blue -underline 1
4957 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
4958 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
4959 $ctext tag bind link0 <1> [list selbyid $oldid]
4960 $ctext insert end $oldid [list link link0]
4961 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004962 $ctext insert end [lindex $commitinfo($oldid) 0]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004963 $ctext insert end "\n\nTo "
4964 $ctext tag bind link1 <1> [list selbyid $newid]
4965 $ctext insert end $newid [list link link1]
4966 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004967 $ctext insert end [lindex $commitinfo($newid) 0]
4968 $ctext insert end "\n"
4969 $ctext conf -state disabled
4970 $ctext tag delete Comments
4971 $ctext tag remove found 1.0 end
Paul Mackerrasd3272442005-11-28 20:41:56 +11004972 startdiff [list $oldid $newid]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004973}
4974
Paul Mackerras74daedb2005-06-27 19:27:32 +10004975proc mkpatch {} {
4976 global rowmenuid currentid commitinfo patchtop patchnum
4977
4978 if {![info exists currentid]} return
4979 set oldid $currentid
4980 set oldhead [lindex $commitinfo($oldid) 0]
4981 set newid $rowmenuid
4982 set newhead [lindex $commitinfo($newid) 0]
4983 set top .patch
4984 set patchtop $top
4985 catch {destroy $top}
4986 toplevel $top
4987 label $top.title -text "Generate patch"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10004988 grid $top.title - -pady 10
Paul Mackerras74daedb2005-06-27 19:27:32 +10004989 label $top.from -text "From:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10004990 entry $top.fromsha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10004991 $top.fromsha1 insert 0 $oldid
4992 $top.fromsha1 conf -state readonly
4993 grid $top.from $top.fromsha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10004994 entry $top.fromhead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10004995 $top.fromhead insert 0 $oldhead
4996 $top.fromhead conf -state readonly
4997 grid x $top.fromhead -sticky w
4998 label $top.to -text "To:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10004999 entry $top.tosha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10005000 $top.tosha1 insert 0 $newid
5001 $top.tosha1 conf -state readonly
5002 grid $top.to $top.tosha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005003 entry $top.tohead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10005004 $top.tohead insert 0 $newhead
5005 $top.tohead conf -state readonly
5006 grid x $top.tohead -sticky w
5007 button $top.rev -text "Reverse" -command mkpatchrev -padx 5
5008 grid $top.rev x -pady 10
5009 label $top.flab -text "Output file:"
5010 entry $top.fname -width 60
5011 $top.fname insert 0 [file normalize "patch$patchnum.patch"]
5012 incr patchnum
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005013 grid $top.flab $top.fname -sticky w
Paul Mackerras74daedb2005-06-27 19:27:32 +10005014 frame $top.buts
5015 button $top.buts.gen -text "Generate" -command mkpatchgo
5016 button $top.buts.can -text "Cancel" -command mkpatchcan
5017 grid $top.buts.gen $top.buts.can
5018 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5019 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5020 grid $top.buts - -pady 10 -sticky ew
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005021 focus $top.fname
Paul Mackerras74daedb2005-06-27 19:27:32 +10005022}
5023
5024proc mkpatchrev {} {
5025 global patchtop
5026
5027 set oldid [$patchtop.fromsha1 get]
5028 set oldhead [$patchtop.fromhead get]
5029 set newid [$patchtop.tosha1 get]
5030 set newhead [$patchtop.tohead get]
5031 foreach e [list fromsha1 fromhead tosha1 tohead] \
5032 v [list $newid $newhead $oldid $oldhead] {
5033 $patchtop.$e conf -state normal
5034 $patchtop.$e delete 0 end
5035 $patchtop.$e insert 0 $v
5036 $patchtop.$e conf -state readonly
5037 }
5038}
5039
5040proc mkpatchgo {} {
5041 global patchtop
5042
5043 set oldid [$patchtop.fromsha1 get]
5044 set newid [$patchtop.tosha1 get]
5045 set fname [$patchtop.fname get]
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03005046 if {[catch {exec git diff-tree -p $oldid $newid >$fname &} err]} {
Paul Mackerras74daedb2005-06-27 19:27:32 +10005047 error_popup "Error creating patch: $err"
5048 }
5049 catch {destroy $patchtop}
5050 unset patchtop
5051}
5052
5053proc mkpatchcan {} {
5054 global patchtop
5055
5056 catch {destroy $patchtop}
5057 unset patchtop
5058}
5059
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005060proc mktag {} {
5061 global rowmenuid mktagtop commitinfo
5062
5063 set top .maketag
5064 set mktagtop $top
5065 catch {destroy $top}
5066 toplevel $top
5067 label $top.title -text "Create tag"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005068 grid $top.title - -pady 10
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005069 label $top.id -text "ID:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005070 entry $top.sha1 -width 40 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005071 $top.sha1 insert 0 $rowmenuid
5072 $top.sha1 conf -state readonly
5073 grid $top.id $top.sha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005074 entry $top.head -width 60 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005075 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
5076 $top.head conf -state readonly
5077 grid x $top.head -sticky w
5078 label $top.tlab -text "Tag name:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005079 entry $top.tag -width 60
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005080 grid $top.tlab $top.tag -sticky w
5081 frame $top.buts
5082 button $top.buts.gen -text "Create" -command mktaggo
5083 button $top.buts.can -text "Cancel" -command mktagcan
5084 grid $top.buts.gen $top.buts.can
5085 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5086 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5087 grid $top.buts - -pady 10 -sticky ew
5088 focus $top.tag
5089}
5090
5091proc domktag {} {
5092 global mktagtop env tagids idtags
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005093
5094 set id [$mktagtop.sha1 get]
5095 set tag [$mktagtop.tag get]
5096 if {$tag == {}} {
5097 error_popup "No tag name specified"
5098 return
5099 }
5100 if {[info exists tagids($tag)]} {
5101 error_popup "Tag \"$tag\" already exists"
5102 return
5103 }
5104 if {[catch {
Junio C Hamano73b6a6c2005-07-28 00:28:44 -07005105 set dir [gitdir]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005106 set fname [file join $dir "refs/tags" $tag]
5107 set f [open $fname w]
5108 puts $f $id
5109 close $f
5110 } err]} {
5111 error_popup "Error creating tag: $err"
5112 return
5113 }
5114
5115 set tagids($tag) $id
5116 lappend idtags($id) $tag
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005117 redrawtags $id
Paul Mackerrasceadfe92006-08-08 20:55:36 +10005118 addedtag $id
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005119}
5120
5121proc redrawtags {id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005122 global canv linehtag commitrow idpos selectedline curview
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005123 global mainfont canvxmax
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005124
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005125 if {![info exists commitrow($curview,$id)]} return
5126 drawcmitrow $commitrow($curview,$id)
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005127 $canv delete tag.$id
5128 set xt [eval drawtags $id $idpos($id)]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005129 $canv coords $linehtag($commitrow($curview,$id)) $xt [lindex $idpos($id) 2]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005130 set text [$canv itemcget $linehtag($commitrow($curview,$id)) -text]
5131 set xr [expr {$xt + [font measure $mainfont $text]}]
5132 if {$xr > $canvxmax} {
5133 set canvxmax $xr
5134 setcanvscroll
5135 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005136 if {[info exists selectedline]
5137 && $selectedline == $commitrow($curview,$id)} {
Paul Mackerrasd6982062005-08-06 22:06:06 +10005138 selectline $selectedline 0
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005139 }
5140}
5141
5142proc mktagcan {} {
5143 global mktagtop
5144
5145 catch {destroy $mktagtop}
5146 unset mktagtop
5147}
5148
5149proc mktaggo {} {
5150 domktag
5151 mktagcan
5152}
5153
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005154proc writecommit {} {
5155 global rowmenuid wrcomtop commitinfo wrcomcmd
5156
5157 set top .writecommit
5158 set wrcomtop $top
5159 catch {destroy $top}
5160 toplevel $top
5161 label $top.title -text "Write commit to file"
5162 grid $top.title - -pady 10
5163 label $top.id -text "ID:"
5164 entry $top.sha1 -width 40 -relief flat
5165 $top.sha1 insert 0 $rowmenuid
5166 $top.sha1 conf -state readonly
5167 grid $top.id $top.sha1 -sticky w
5168 entry $top.head -width 60 -relief flat
5169 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
5170 $top.head conf -state readonly
5171 grid x $top.head -sticky w
5172 label $top.clab -text "Command:"
5173 entry $top.cmd -width 60 -textvariable wrcomcmd
5174 grid $top.clab $top.cmd -sticky w -pady 10
5175 label $top.flab -text "Output file:"
5176 entry $top.fname -width 60
5177 $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"]
5178 grid $top.flab $top.fname -sticky w
5179 frame $top.buts
5180 button $top.buts.gen -text "Write" -command wrcomgo
5181 button $top.buts.can -text "Cancel" -command wrcomcan
5182 grid $top.buts.gen $top.buts.can
5183 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5184 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5185 grid $top.buts - -pady 10 -sticky ew
5186 focus $top.fname
5187}
5188
5189proc wrcomgo {} {
5190 global wrcomtop
5191
5192 set id [$wrcomtop.sha1 get]
5193 set cmd "echo $id | [$wrcomtop.cmd get]"
5194 set fname [$wrcomtop.fname get]
5195 if {[catch {exec sh -c $cmd >$fname &} err]} {
5196 error_popup "Error writing commit: $err"
5197 }
5198 catch {destroy $wrcomtop}
5199 unset wrcomtop
5200}
5201
5202proc wrcomcan {} {
5203 global wrcomtop
5204
5205 catch {destroy $wrcomtop}
5206 unset wrcomtop
5207}
5208
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005209proc mkbranch {} {
5210 global rowmenuid mkbrtop
5211
5212 set top .makebranch
5213 catch {destroy $top}
5214 toplevel $top
5215 label $top.title -text "Create new branch"
5216 grid $top.title - -pady 10
5217 label $top.id -text "ID:"
5218 entry $top.sha1 -width 40 -relief flat
5219 $top.sha1 insert 0 $rowmenuid
5220 $top.sha1 conf -state readonly
5221 grid $top.id $top.sha1 -sticky w
5222 label $top.nlab -text "Name:"
5223 entry $top.name -width 40
5224 grid $top.nlab $top.name -sticky w
5225 frame $top.buts
5226 button $top.buts.go -text "Create" -command [list mkbrgo $top]
5227 button $top.buts.can -text "Cancel" -command "catch {destroy $top}"
5228 grid $top.buts.go $top.buts.can
5229 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5230 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5231 grid $top.buts - -pady 10 -sticky ew
5232 focus $top.name
5233}
5234
5235proc mkbrgo {top} {
5236 global headids idheads
5237
5238 set name [$top.name get]
5239 set id [$top.sha1 get]
5240 if {$name eq {}} {
5241 error_popup "Please specify a name for the new branch"
5242 return
5243 }
5244 catch {destroy $top}
5245 nowbusy newbranch
5246 update
5247 if {[catch {
5248 exec git branch $name $id
5249 } err]} {
5250 notbusy newbranch
5251 error_popup $err
5252 } else {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005253 addedhead $id $name
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005254 # XXX should update list of heads displayed for selected commit
5255 notbusy newbranch
5256 redrawtags $id
5257 }
5258}
5259
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005260proc cherrypick {} {
5261 global rowmenuid curview commitrow
5262 global mainhead desc_heads anc_tags desc_tags allparents allchildren
5263
5264 if {[info exists desc_heads($rowmenuid)]
5265 && [lsearch -exact $desc_heads($rowmenuid) $mainhead] >= 0} {
5266 set ok [confirm_popup "Commit [string range $rowmenuid 0 7] is already\
5267 included in branch $mainhead -- really re-apply it?"]
5268 if {!$ok} return
5269 }
5270 nowbusy cherrypick
5271 update
5272 set oldhead [exec git rev-parse HEAD]
5273 # Unfortunately git-cherry-pick writes stuff to stderr even when
5274 # no error occurs, and exec takes that as an indication of error...
5275 if {[catch {exec sh -c "git cherry-pick -r $rowmenuid 2>&1"} err]} {
5276 notbusy cherrypick
5277 error_popup $err
5278 return
5279 }
5280 set newhead [exec git rev-parse HEAD]
5281 if {$newhead eq $oldhead} {
5282 notbusy cherrypick
5283 error_popup "No changes committed"
5284 return
5285 }
5286 set allparents($newhead) $oldhead
5287 lappend allchildren($oldhead) $newhead
5288 set desc_heads($newhead) $mainhead
5289 if {[info exists anc_tags($oldhead)]} {
5290 set anc_tags($newhead) $anc_tags($oldhead)
5291 }
5292 set desc_tags($newhead) {}
5293 if {[info exists commitrow($curview,$oldhead)]} {
5294 insertrow $commitrow($curview,$oldhead) $newhead
5295 if {$mainhead ne {}} {
5296 movedhead $newhead $mainhead
5297 }
5298 redrawtags $oldhead
5299 redrawtags $newhead
5300 }
5301 notbusy cherrypick
5302}
5303
Paul Mackerras10299152006-08-02 09:52:01 +10005304# context menu for a head
5305proc headmenu {x y id head} {
5306 global headmenuid headmenuhead headctxmenu
5307
5308 set headmenuid $id
5309 set headmenuhead $head
5310 tk_popup $headctxmenu $x $y
5311}
5312
5313proc cobranch {} {
5314 global headmenuid headmenuhead mainhead headids
5315
5316 # check the tree is clean first??
5317 set oldmainhead $mainhead
5318 nowbusy checkout
5319 update
5320 if {[catch {
5321 exec git checkout $headmenuhead
5322 } err]} {
5323 notbusy checkout
5324 error_popup $err
5325 } else {
5326 notbusy checkout
Paul Mackerras53cda8d2006-08-02 19:43:34 +10005327 set mainhead $headmenuhead
Paul Mackerras10299152006-08-02 09:52:01 +10005328 if {[info exists headids($oldmainhead)]} {
5329 redrawtags $headids($oldmainhead)
5330 }
5331 redrawtags $headmenuid
5332 }
5333}
5334
5335proc rmbranch {} {
5336 global desc_heads headmenuid headmenuhead mainhead
5337 global headids idheads
5338
5339 set head $headmenuhead
5340 set id $headmenuid
5341 if {$head eq $mainhead} {
5342 error_popup "Cannot delete the currently checked-out branch"
5343 return
5344 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005345 if {$desc_heads($id) eq $head} {
Paul Mackerras10299152006-08-02 09:52:01 +10005346 # the stuff on this branch isn't on any other branch
5347 if {![confirm_popup "The commits on branch $head aren't on any other\
5348 branch.\nReally delete branch $head?"]} return
5349 }
5350 nowbusy rmbranch
5351 update
5352 if {[catch {exec git branch -D $head} err]} {
5353 notbusy rmbranch
5354 error_popup $err
5355 return
5356 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005357 removedhead $id $head
Paul Mackerras10299152006-08-02 09:52:01 +10005358 redrawtags $id
5359 notbusy rmbranch
5360}
5361
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005362# Stuff for finding nearby tags
5363proc getallcommits {} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005364 global allcstart allcommits allcfd allids
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005365
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005366 set allids {}
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005367 set fd [open [concat | git rev-list --all --topo-order --parents] r]
Paul Mackerras2d71bcc2006-06-07 09:19:45 +10005368 set allcfd $fd
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005369 fconfigure $fd -blocking 0
5370 set allcommits "reading"
5371 nowbusy allcommits
5372 restartgetall $fd
5373}
5374
Paul Mackerras2d71bcc2006-06-07 09:19:45 +10005375proc discardallcommits {} {
5376 global allparents allchildren allcommits allcfd
5377 global desc_tags anc_tags alldtags tagisdesc allids desc_heads
5378
5379 if {![info exists allcommits]} return
5380 if {$allcommits eq "reading"} {
5381 catch {close $allcfd}
5382 }
5383 foreach v {allcommits allchildren allparents allids desc_tags anc_tags
5384 alldtags tagisdesc desc_heads} {
5385 catch {unset $v}
5386 }
5387}
5388
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005389proc restartgetall {fd} {
5390 global allcstart
5391
5392 fileevent $fd readable [list getallclines $fd]
5393 set allcstart [clock clicks -milliseconds]
5394}
5395
5396proc combine_dtags {l1 l2} {
5397 global tagisdesc notfirstd
5398
5399 set res [lsort -unique [concat $l1 $l2]]
5400 for {set i 0} {$i < [llength $res]} {incr i} {
5401 set x [lindex $res $i]
5402 for {set j [expr {$i+1}]} {$j < [llength $res]} {} {
5403 set y [lindex $res $j]
5404 if {[info exists tagisdesc($x,$y)]} {
5405 if {$tagisdesc($x,$y) > 0} {
5406 # x is a descendent of y, exclude x
5407 set res [lreplace $res $i $i]
5408 incr i -1
5409 break
5410 } else {
5411 # y is a descendent of x, exclude y
5412 set res [lreplace $res $j $j]
5413 }
5414 } else {
5415 # no relation, keep going
5416 incr j
5417 }
5418 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005419 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005420 return $res
5421}
5422
5423proc combine_atags {l1 l2} {
5424 global tagisdesc
5425
5426 set res [lsort -unique [concat $l1 $l2]]
5427 for {set i 0} {$i < [llength $res]} {incr i} {
5428 set x [lindex $res $i]
5429 for {set j [expr {$i+1}]} {$j < [llength $res]} {} {
5430 set y [lindex $res $j]
5431 if {[info exists tagisdesc($x,$y)]} {
5432 if {$tagisdesc($x,$y) < 0} {
5433 # x is an ancestor of y, exclude x
5434 set res [lreplace $res $i $i]
5435 incr i -1
5436 break
5437 } else {
5438 # y is an ancestor of x, exclude y
5439 set res [lreplace $res $j $j]
5440 }
5441 } else {
5442 # no relation, keep going
5443 incr j
5444 }
5445 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005446 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005447 return $res
5448}
5449
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005450proc forward_pass {id children} {
5451 global idtags desc_tags idheads desc_heads alldtags tagisdesc
5452
5453 set dtags {}
5454 set dheads {}
5455 foreach child $children {
5456 if {[info exists idtags($child)]} {
5457 set ctags [list $child]
5458 } else {
5459 set ctags $desc_tags($child)
5460 }
5461 if {$dtags eq {}} {
5462 set dtags $ctags
5463 } elseif {$ctags ne $dtags} {
5464 set dtags [combine_dtags $dtags $ctags]
5465 }
5466 set cheads $desc_heads($child)
5467 if {$dheads eq {}} {
5468 set dheads $cheads
5469 } elseif {$cheads ne $dheads} {
5470 set dheads [lsort -unique [concat $dheads $cheads]]
5471 }
5472 }
5473 set desc_tags($id) $dtags
5474 if {[info exists idtags($id)]} {
5475 set adt $dtags
5476 foreach tag $dtags {
5477 set adt [concat $adt $alldtags($tag)]
5478 }
5479 set adt [lsort -unique $adt]
5480 set alldtags($id) $adt
5481 foreach tag $adt {
5482 set tagisdesc($id,$tag) -1
5483 set tagisdesc($tag,$id) 1
5484 }
5485 }
5486 if {[info exists idheads($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005487 set dheads [concat $dheads $idheads($id)]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005488 }
5489 set desc_heads($id) $dheads
5490}
5491
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005492proc getallclines {fd} {
5493 global allparents allchildren allcommits allcstart
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005494 global desc_tags anc_tags idtags tagisdesc allids
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005495 global idheads travindex
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005496
5497 while {[gets $fd line] >= 0} {
5498 set id [lindex $line 0]
5499 lappend allids $id
5500 set olds [lrange $line 1 end]
5501 set allparents($id) $olds
5502 if {![info exists allchildren($id)]} {
5503 set allchildren($id) {}
5504 }
5505 foreach p $olds {
5506 lappend allchildren($p) $id
5507 }
5508 # compute nearest tagged descendents as we go
Paul Mackerrasef030b82006-06-04 11:50:38 +10005509 # also compute descendent heads
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005510 forward_pass $id $allchildren($id)
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005511 if {[clock clicks -milliseconds] - $allcstart >= 50} {
5512 fileevent $fd readable {}
5513 after idle restartgetall $fd
5514 return
5515 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005516 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005517 if {[eof $fd]} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005518 set travindex [llength $allids]
5519 set allcommits "traversing"
5520 after idle restartatags
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005521 if {[catch {close $fd} err]} {
5522 error_popup "Error reading full commit graph: $err.\n\
5523 Results may be incomplete."
5524 }
5525 }
5526}
5527
5528# walk backward through the tree and compute nearest tagged ancestors
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005529proc restartatags {} {
5530 global allids allparents idtags anc_tags travindex
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005531
5532 set t0 [clock clicks -milliseconds]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005533 set i $travindex
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005534 while {[incr i -1] >= 0} {
5535 set id [lindex $allids $i]
5536 set atags {}
5537 foreach p $allparents($id) {
5538 if {[info exists idtags($p)]} {
5539 set ptags [list $p]
5540 } else {
5541 set ptags $anc_tags($p)
5542 }
5543 if {$atags eq {}} {
5544 set atags $ptags
5545 } elseif {$ptags ne $atags} {
5546 set atags [combine_atags $atags $ptags]
5547 }
5548 }
5549 set anc_tags($id) $atags
5550 if {[clock clicks -milliseconds] - $t0 >= 50} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005551 set travindex $i
5552 after idle restartatags
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005553 return
5554 }
5555 }
5556 set allcommits "done"
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005557 set travindex 0
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005558 notbusy allcommits
5559 dispneartags
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005560}
5561
Paul Mackerrasceadfe92006-08-08 20:55:36 +10005562# update the desc_tags and anc_tags arrays for a new tag just added
5563proc addedtag {id} {
5564 global desc_tags anc_tags allparents allchildren allcommits
5565 global idtags tagisdesc alldtags
5566
5567 if {![info exists desc_tags($id)]} return
5568 set adt $desc_tags($id)
5569 foreach t $desc_tags($id) {
5570 set adt [concat $adt $alldtags($t)]
5571 }
5572 set adt [lsort -unique $adt]
5573 set alldtags($id) $adt
5574 foreach t $adt {
5575 set tagisdesc($id,$t) -1
5576 set tagisdesc($t,$id) 1
5577 }
5578 if {[info exists anc_tags($id)]} {
5579 set todo $anc_tags($id)
5580 while {$todo ne {}} {
5581 set do [lindex $todo 0]
5582 set todo [lrange $todo 1 end]
5583 if {[info exists tagisdesc($id,$do)]} continue
5584 set tagisdesc($do,$id) -1
5585 set tagisdesc($id,$do) 1
5586 if {[info exists anc_tags($do)]} {
5587 set todo [concat $todo $anc_tags($do)]
5588 }
5589 }
5590 }
5591
5592 set lastold $desc_tags($id)
5593 set lastnew [list $id]
5594 set nup 0
5595 set nch 0
5596 set todo $allparents($id)
5597 while {$todo ne {}} {
5598 set do [lindex $todo 0]
5599 set todo [lrange $todo 1 end]
5600 if {![info exists desc_tags($do)]} continue
5601 if {$desc_tags($do) ne $lastold} {
5602 set lastold $desc_tags($do)
5603 set lastnew [combine_dtags $lastold [list $id]]
5604 incr nch
5605 }
5606 if {$lastold eq $lastnew} continue
5607 set desc_tags($do) $lastnew
5608 incr nup
5609 if {![info exists idtags($do)]} {
5610 set todo [concat $todo $allparents($do)]
5611 }
5612 }
5613
5614 if {![info exists anc_tags($id)]} return
5615 set lastold $anc_tags($id)
5616 set lastnew [list $id]
5617 set nup 0
5618 set nch 0
5619 set todo $allchildren($id)
5620 while {$todo ne {}} {
5621 set do [lindex $todo 0]
5622 set todo [lrange $todo 1 end]
5623 if {![info exists anc_tags($do)]} continue
5624 if {$anc_tags($do) ne $lastold} {
5625 set lastold $anc_tags($do)
5626 set lastnew [combine_atags $lastold [list $id]]
5627 incr nch
5628 }
5629 if {$lastold eq $lastnew} continue
5630 set anc_tags($do) $lastnew
5631 incr nup
5632 if {![info exists idtags($do)]} {
5633 set todo [concat $todo $allchildren($do)]
5634 }
5635 }
5636}
5637
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005638# update the desc_heads array for a new head just added
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005639proc addedhead {hid head} {
5640 global desc_heads allparents headids idheads
5641
5642 set headids($head) $hid
5643 lappend idheads($hid) $head
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005644
5645 set todo [list $hid]
5646 while {$todo ne {}} {
5647 set do [lindex $todo 0]
5648 set todo [lrange $todo 1 end]
5649 if {![info exists desc_heads($do)] ||
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005650 [lsearch -exact $desc_heads($do) $head] >= 0} continue
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005651 set oldheads $desc_heads($do)
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005652 lappend desc_heads($do) $head
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005653 set heads $desc_heads($do)
5654 while {1} {
5655 set p $allparents($do)
5656 if {[llength $p] != 1 || ![info exists desc_heads($p)] ||
5657 $desc_heads($p) ne $oldheads} break
5658 set do $p
5659 set desc_heads($do) $heads
5660 }
5661 set todo [concat $todo $p]
5662 }
5663}
5664
Paul Mackerras10299152006-08-02 09:52:01 +10005665# update the desc_heads array for a head just removed
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005666proc removedhead {hid head} {
5667 global desc_heads allparents headids idheads
5668
5669 unset headids($head)
5670 if {$idheads($hid) eq $head} {
5671 unset idheads($hid)
5672 } else {
5673 set i [lsearch -exact $idheads($hid) $head]
5674 if {$i >= 0} {
5675 set idheads($hid) [lreplace $idheads($hid) $i $i]
5676 }
5677 }
Paul Mackerras10299152006-08-02 09:52:01 +10005678
5679 set todo [list $hid]
5680 while {$todo ne {}} {
5681 set do [lindex $todo 0]
5682 set todo [lrange $todo 1 end]
5683 if {![info exists desc_heads($do)]} continue
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005684 set i [lsearch -exact $desc_heads($do) $head]
Paul Mackerras10299152006-08-02 09:52:01 +10005685 if {$i < 0} continue
5686 set oldheads $desc_heads($do)
5687 set heads [lreplace $desc_heads($do) $i $i]
5688 while {1} {
5689 set desc_heads($do) $heads
5690 set p $allparents($do)
5691 if {[llength $p] != 1 || ![info exists desc_heads($p)] ||
5692 $desc_heads($p) ne $oldheads} break
5693 set do $p
5694 }
5695 set todo [concat $todo $p]
5696 }
5697}
5698
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005699# update things for a head moved to a child of its previous location
5700proc movedhead {id name} {
5701 global headids idheads
5702
5703 set oldid $headids($name)
5704 set headids($name) $id
5705 if {$idheads($oldid) eq $name} {
5706 unset idheads($oldid)
5707 } else {
5708 set i [lsearch -exact $idheads($oldid) $name]
5709 if {$i >= 0} {
5710 set idheads($oldid) [lreplace $idheads($oldid) $i $i]
5711 }
5712 }
5713 lappend idheads($id) $name
5714}
5715
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005716proc changedrefs {} {
5717 global desc_heads desc_tags anc_tags allcommits allids
5718 global allchildren allparents idtags travindex
5719
5720 if {![info exists allcommits]} return
5721 catch {unset desc_heads}
5722 catch {unset desc_tags}
5723 catch {unset anc_tags}
5724 catch {unset alldtags}
5725 catch {unset tagisdesc}
5726 foreach id $allids {
5727 forward_pass $id $allchildren($id)
5728 }
5729 if {$allcommits ne "reading"} {
5730 set travindex [llength $allids]
5731 if {$allcommits ne "traversing"} {
5732 set allcommits "traversing"
5733 after idle restartatags
5734 }
5735 }
5736}
5737
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005738proc rereadrefs {} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005739 global idtags idheads idotherrefs mainhead
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005740
5741 set refids [concat [array names idtags] \
5742 [array names idheads] [array names idotherrefs]]
5743 foreach id $refids {
5744 if {![info exists ref($id)]} {
5745 set ref($id) [listrefs $id]
5746 }
5747 }
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005748 set oldmainhead $mainhead
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005749 readrefs
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005750 changedrefs
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005751 set refids [lsort -unique [concat $refids [array names idtags] \
5752 [array names idheads] [array names idotherrefs]]]
5753 foreach id $refids {
5754 set v [listrefs $id]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005755 if {![info exists ref($id)] || $ref($id) != $v ||
5756 ($id eq $oldmainhead && $id ne $mainhead) ||
5757 ($id eq $mainhead && $id ne $oldmainhead)} {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005758 redrawtags $id
5759 }
5760 }
5761}
5762
Junio C Hamano2e1ded42006-06-11 09:50:47 -07005763proc listrefs {id} {
5764 global idtags idheads idotherrefs
5765
5766 set x {}
5767 if {[info exists idtags($id)]} {
5768 set x $idtags($id)
5769 }
5770 set y {}
5771 if {[info exists idheads($id)]} {
5772 set y $idheads($id)
5773 }
5774 set z {}
5775 if {[info exists idotherrefs($id)]} {
5776 set z $idotherrefs($id)
5777 }
5778 return [list $x $y $z]
5779}
5780
Paul Mackerras106288c2005-08-19 23:11:39 +10005781proc showtag {tag isnew} {
Paul Mackerras7fcceed2006-04-27 19:21:49 +10005782 global ctext tagcontents tagids linknum
Paul Mackerras106288c2005-08-19 23:11:39 +10005783
5784 if {$isnew} {
5785 addtohistory [list showtag $tag 0]
5786 }
5787 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10005788 clear_ctext
Paul Mackerras106288c2005-08-19 23:11:39 +10005789 set linknum 0
5790 if {[info exists tagcontents($tag)]} {
5791 set text $tagcontents($tag)
5792 } else {
5793 set text "Tag: $tag\nId: $tagids($tag)"
5794 }
Sergey Vlasovf1b86292006-05-15 19:13:14 +04005795 appendwithlinks $text {}
Paul Mackerras106288c2005-08-19 23:11:39 +10005796 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10005797 init_flist {}
Paul Mackerras106288c2005-08-19 23:11:39 +10005798}
5799
Paul Mackerras1d10f362005-05-15 12:55:47 +00005800proc doquit {} {
5801 global stopped
5802 set stopped 100
Mark Levedahlb6047c52007-02-08 22:22:24 -05005803 savestuff .
Paul Mackerras1d10f362005-05-15 12:55:47 +00005804 destroy .
5805}
5806
Paul Mackerras712fcc02005-11-30 09:28:16 +11005807proc doprefs {} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10005808 global maxwidth maxgraphpct diffopts
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005809 global oldprefs prefstop showneartags
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005810 global bgcolor fgcolor ctext diffcolors
Paul Mackerras232475d2005-11-15 10:34:03 +11005811
Paul Mackerras712fcc02005-11-30 09:28:16 +11005812 set top .gitkprefs
5813 set prefstop $top
5814 if {[winfo exists $top]} {
5815 raise $top
5816 return
Paul Mackerras757f17b2005-11-21 09:56:07 +11005817 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005818 foreach v {maxwidth maxgraphpct diffopts showneartags} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11005819 set oldprefs($v) [set $v]
Paul Mackerras232475d2005-11-15 10:34:03 +11005820 }
Paul Mackerras712fcc02005-11-30 09:28:16 +11005821 toplevel $top
5822 wm title $top "Gitk preferences"
5823 label $top.ldisp -text "Commit list display options"
5824 grid $top.ldisp - -sticky w -pady 10
5825 label $top.spacer -text " "
5826 label $top.maxwidthl -text "Maximum graph width (lines)" \
5827 -font optionfont
5828 spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
5829 grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
5830 label $top.maxpctl -text "Maximum graph width (% of pane)" \
5831 -font optionfont
5832 spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
5833 grid x $top.maxpctl $top.maxpct -sticky w
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005834
Paul Mackerras712fcc02005-11-30 09:28:16 +11005835 label $top.ddisp -text "Diff display options"
5836 grid $top.ddisp - -sticky w -pady 10
5837 label $top.diffoptl -text "Options for diff program" \
5838 -font optionfont
5839 entry $top.diffopt -width 20 -textvariable diffopts
5840 grid x $top.diffoptl $top.diffopt -sticky w
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005841 frame $top.ntag
5842 label $top.ntag.l -text "Display nearby tags" -font optionfont
5843 checkbutton $top.ntag.b -variable showneartags
5844 pack $top.ntag.b $top.ntag.l -side left
5845 grid x $top.ntag -sticky w
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005846
5847 label $top.cdisp -text "Colors: press to choose"
5848 grid $top.cdisp - -sticky w -pady 10
5849 label $top.bg -padx 40 -relief sunk -background $bgcolor
5850 button $top.bgbut -text "Background" -font optionfont \
5851 -command [list choosecolor bgcolor 0 $top.bg background setbg]
5852 grid x $top.bgbut $top.bg -sticky w
5853 label $top.fg -padx 40 -relief sunk -background $fgcolor
5854 button $top.fgbut -text "Foreground" -font optionfont \
5855 -command [list choosecolor fgcolor 0 $top.fg foreground setfg]
5856 grid x $top.fgbut $top.fg -sticky w
5857 label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
5858 button $top.diffoldbut -text "Diff: old lines" -font optionfont \
5859 -command [list choosecolor diffcolors 0 $top.diffold "diff old lines" \
5860 [list $ctext tag conf d0 -foreground]]
5861 grid x $top.diffoldbut $top.diffold -sticky w
5862 label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
5863 button $top.diffnewbut -text "Diff: new lines" -font optionfont \
5864 -command [list choosecolor diffcolors 1 $top.diffnew "diff new lines" \
5865 [list $ctext tag conf d1 -foreground]]
5866 grid x $top.diffnewbut $top.diffnew -sticky w
5867 label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
5868 button $top.hunksepbut -text "Diff: hunk header" -font optionfont \
5869 -command [list choosecolor diffcolors 2 $top.hunksep \
5870 "diff hunk header" \
5871 [list $ctext tag conf hunksep -foreground]]
5872 grid x $top.hunksepbut $top.hunksep -sticky w
5873
Paul Mackerras712fcc02005-11-30 09:28:16 +11005874 frame $top.buts
5875 button $top.buts.ok -text "OK" -command prefsok
5876 button $top.buts.can -text "Cancel" -command prefscan
5877 grid $top.buts.ok $top.buts.can
5878 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5879 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5880 grid $top.buts - - -pady 10 -sticky ew
5881}
5882
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005883proc choosecolor {v vi w x cmd} {
5884 global $v
5885
5886 set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \
5887 -title "Gitk: choose color for $x"]
5888 if {$c eq {}} return
5889 $w conf -background $c
5890 lset $v $vi $c
5891 eval $cmd $c
5892}
5893
5894proc setbg {c} {
5895 global bglist
5896
5897 foreach w $bglist {
5898 $w conf -background $c
5899 }
5900}
5901
5902proc setfg {c} {
5903 global fglist canv
5904
5905 foreach w $fglist {
5906 $w conf -foreground $c
5907 }
5908 allcanvs itemconf text -fill $c
5909 $canv itemconf circle -outline $c
5910}
5911
Paul Mackerras712fcc02005-11-30 09:28:16 +11005912proc prefscan {} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10005913 global maxwidth maxgraphpct diffopts
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005914 global oldprefs prefstop showneartags
Paul Mackerras712fcc02005-11-30 09:28:16 +11005915
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005916 foreach v {maxwidth maxgraphpct diffopts showneartags} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11005917 set $v $oldprefs($v)
5918 }
5919 catch {destroy $prefstop}
5920 unset prefstop
5921}
5922
5923proc prefsok {} {
5924 global maxwidth maxgraphpct
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005925 global oldprefs prefstop showneartags
Paul Mackerras712fcc02005-11-30 09:28:16 +11005926
5927 catch {destroy $prefstop}
5928 unset prefstop
5929 if {$maxwidth != $oldprefs(maxwidth)
5930 || $maxgraphpct != $oldprefs(maxgraphpct)} {
5931 redisplay
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005932 } elseif {$showneartags != $oldprefs(showneartags)} {
5933 reselectline
Paul Mackerras712fcc02005-11-30 09:28:16 +11005934 }
5935}
5936
5937proc formatdate {d} {
5938 return [clock format $d -format "%Y-%m-%d %H:%M:%S"]
Paul Mackerras232475d2005-11-15 10:34:03 +11005939}
5940
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11005941# This list of encoding names and aliases is distilled from
5942# http://www.iana.org/assignments/character-sets.
5943# Not all of them are supported by Tcl.
5944set encoding_aliases {
5945 { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII
5946 ISO646-US US-ASCII us IBM367 cp367 csASCII }
5947 { ISO-10646-UTF-1 csISO10646UTF1 }
5948 { ISO_646.basic:1983 ref csISO646basic1983 }
5949 { INVARIANT csINVARIANT }
5950 { ISO_646.irv:1983 iso-ir-2 irv csISO2IntlRefVersion }
5951 { BS_4730 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom }
5952 { NATS-SEFI iso-ir-8-1 csNATSSEFI }
5953 { NATS-SEFI-ADD iso-ir-8-2 csNATSSEFIADD }
5954 { NATS-DANO iso-ir-9-1 csNATSDANO }
5955 { NATS-DANO-ADD iso-ir-9-2 csNATSDANOADD }
5956 { SEN_850200_B iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish }
5957 { SEN_850200_C iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames }
5958 { KS_C_5601-1987 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 }
5959 { ISO-2022-KR csISO2022KR }
5960 { EUC-KR csEUCKR }
5961 { ISO-2022-JP csISO2022JP }
5962 { ISO-2022-JP-2 csISO2022JP2 }
5963 { JIS_C6220-1969-jp JIS_C6220-1969 iso-ir-13 katakana x0201-7
5964 csISO13JISC6220jp }
5965 { JIS_C6220-1969-ro iso-ir-14 jp ISO646-JP csISO14JISC6220ro }
5966 { IT iso-ir-15 ISO646-IT csISO15Italian }
5967 { PT iso-ir-16 ISO646-PT csISO16Portuguese }
5968 { ES iso-ir-17 ISO646-ES csISO17Spanish }
5969 { greek7-old iso-ir-18 csISO18Greek7Old }
5970 { latin-greek iso-ir-19 csISO19LatinGreek }
5971 { DIN_66003 iso-ir-21 de ISO646-DE csISO21German }
5972 { NF_Z_62-010_(1973) iso-ir-25 ISO646-FR1 csISO25French }
5973 { Latin-greek-1 iso-ir-27 csISO27LatinGreek1 }
5974 { ISO_5427 iso-ir-37 csISO5427Cyrillic }
5975 { JIS_C6226-1978 iso-ir-42 csISO42JISC62261978 }
5976 { BS_viewdata iso-ir-47 csISO47BSViewdata }
5977 { INIS iso-ir-49 csISO49INIS }
5978 { INIS-8 iso-ir-50 csISO50INIS8 }
5979 { INIS-cyrillic iso-ir-51 csISO51INISCyrillic }
5980 { ISO_5427:1981 iso-ir-54 ISO5427Cyrillic1981 }
5981 { ISO_5428:1980 iso-ir-55 csISO5428Greek }
5982 { GB_1988-80 iso-ir-57 cn ISO646-CN csISO57GB1988 }
5983 { GB_2312-80 iso-ir-58 chinese csISO58GB231280 }
5984 { NS_4551-1 iso-ir-60 ISO646-NO no csISO60DanishNorwegian
5985 csISO60Norwegian1 }
5986 { NS_4551-2 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 }
5987 { NF_Z_62-010 iso-ir-69 ISO646-FR fr csISO69French }
5988 { videotex-suppl iso-ir-70 csISO70VideotexSupp1 }
5989 { PT2 iso-ir-84 ISO646-PT2 csISO84Portuguese2 }
5990 { ES2 iso-ir-85 ISO646-ES2 csISO85Spanish2 }
5991 { MSZ_7795.3 iso-ir-86 ISO646-HU hu csISO86Hungarian }
5992 { JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 }
5993 { greek7 iso-ir-88 csISO88Greek7 }
5994 { ASMO_449 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 }
5995 { iso-ir-90 csISO90 }
5996 { JIS_C6229-1984-a iso-ir-91 jp-ocr-a csISO91JISC62291984a }
5997 { JIS_C6229-1984-b iso-ir-92 ISO646-JP-OCR-B jp-ocr-b
5998 csISO92JISC62991984b }
5999 { JIS_C6229-1984-b-add iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd }
6000 { JIS_C6229-1984-hand iso-ir-94 jp-ocr-hand csISO94JIS62291984hand }
6001 { JIS_C6229-1984-hand-add iso-ir-95 jp-ocr-hand-add
6002 csISO95JIS62291984handadd }
6003 { JIS_C6229-1984-kana iso-ir-96 csISO96JISC62291984kana }
6004 { ISO_2033-1983 iso-ir-98 e13b csISO2033 }
6005 { ANSI_X3.110-1983 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS }
6006 { ISO_8859-1:1987 iso-ir-100 ISO_8859-1 ISO-8859-1 latin1 l1 IBM819
6007 CP819 csISOLatin1 }
6008 { ISO_8859-2:1987 iso-ir-101 ISO_8859-2 ISO-8859-2 latin2 l2 csISOLatin2 }
6009 { T.61-7bit iso-ir-102 csISO102T617bit }
6010 { T.61-8bit T.61 iso-ir-103 csISO103T618bit }
6011 { ISO_8859-3:1988 iso-ir-109 ISO_8859-3 ISO-8859-3 latin3 l3 csISOLatin3 }
6012 { ISO_8859-4:1988 iso-ir-110 ISO_8859-4 ISO-8859-4 latin4 l4 csISOLatin4 }
6013 { ECMA-cyrillic iso-ir-111 KOI8-E csISO111ECMACyrillic }
6014 { CSA_Z243.4-1985-1 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 }
6015 { CSA_Z243.4-1985-2 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 }
6016 { CSA_Z243.4-1985-gr iso-ir-123 csISO123CSAZ24341985gr }
6017 { ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ISO-8859-6 ECMA-114 ASMO-708
6018 arabic csISOLatinArabic }
6019 { ISO_8859-6-E csISO88596E ISO-8859-6-E }
6020 { ISO_8859-6-I csISO88596I ISO-8859-6-I }
6021 { ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ISO-8859-7 ELOT_928 ECMA-118
6022 greek greek8 csISOLatinGreek }
6023 { T.101-G2 iso-ir-128 csISO128T101G2 }
6024 { ISO_8859-8:1988 iso-ir-138 ISO_8859-8 ISO-8859-8 hebrew
6025 csISOLatinHebrew }
6026 { ISO_8859-8-E csISO88598E ISO-8859-8-E }
6027 { ISO_8859-8-I csISO88598I ISO-8859-8-I }
6028 { CSN_369103 iso-ir-139 csISO139CSN369103 }
6029 { JUS_I.B1.002 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 }
6030 { ISO_6937-2-add iso-ir-142 csISOTextComm }
6031 { IEC_P27-1 iso-ir-143 csISO143IECP271 }
6032 { ISO_8859-5:1988 iso-ir-144 ISO_8859-5 ISO-8859-5 cyrillic
6033 csISOLatinCyrillic }
6034 { JUS_I.B1.003-serb iso-ir-146 serbian csISO146Serbian }
6035 { JUS_I.B1.003-mac macedonian iso-ir-147 csISO147Macedonian }
6036 { ISO_8859-9:1989 iso-ir-148 ISO_8859-9 ISO-8859-9 latin5 l5 csISOLatin5 }
6037 { greek-ccitt iso-ir-150 csISO150 csISO150GreekCCITT }
6038 { NC_NC00-10:81 cuba iso-ir-151 ISO646-CU csISO151Cuba }
6039 { ISO_6937-2-25 iso-ir-152 csISO6937Add }
6040 { GOST_19768-74 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 }
6041 { ISO_8859-supp iso-ir-154 latin1-2-5 csISO8859Supp }
6042 { ISO_10367-box iso-ir-155 csISO10367Box }
6043 { ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 }
6044 { latin-lap lap iso-ir-158 csISO158Lap }
6045 { JIS_X0212-1990 x0212 iso-ir-159 csISO159JISX02121990 }
6046 { DS_2089 DS2089 ISO646-DK dk csISO646Danish }
6047 { us-dk csUSDK }
6048 { dk-us csDKUS }
6049 { JIS_X0201 X0201 csHalfWidthKatakana }
6050 { KSC5636 ISO646-KR csKSC5636 }
6051 { ISO-10646-UCS-2 csUnicode }
6052 { ISO-10646-UCS-4 csUCS4 }
6053 { DEC-MCS dec csDECMCS }
6054 { hp-roman8 roman8 r8 csHPRoman8 }
6055 { macintosh mac csMacintosh }
6056 { IBM037 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl
6057 csIBM037 }
6058 { IBM038 EBCDIC-INT cp038 csIBM038 }
6059 { IBM273 CP273 csIBM273 }
6060 { IBM274 EBCDIC-BE CP274 csIBM274 }
6061 { IBM275 EBCDIC-BR cp275 csIBM275 }
6062 { IBM277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 }
6063 { IBM278 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 }
6064 { IBM280 CP280 ebcdic-cp-it csIBM280 }
6065 { IBM281 EBCDIC-JP-E cp281 csIBM281 }
6066 { IBM284 CP284 ebcdic-cp-es csIBM284 }
6067 { IBM285 CP285 ebcdic-cp-gb csIBM285 }
6068 { IBM290 cp290 EBCDIC-JP-kana csIBM290 }
6069 { IBM297 cp297 ebcdic-cp-fr csIBM297 }
6070 { IBM420 cp420 ebcdic-cp-ar1 csIBM420 }
6071 { IBM423 cp423 ebcdic-cp-gr csIBM423 }
6072 { IBM424 cp424 ebcdic-cp-he csIBM424 }
6073 { IBM437 cp437 437 csPC8CodePage437 }
6074 { IBM500 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 }
6075 { IBM775 cp775 csPC775Baltic }
6076 { IBM850 cp850 850 csPC850Multilingual }
6077 { IBM851 cp851 851 csIBM851 }
6078 { IBM852 cp852 852 csPCp852 }
6079 { IBM855 cp855 855 csIBM855 }
6080 { IBM857 cp857 857 csIBM857 }
6081 { IBM860 cp860 860 csIBM860 }
6082 { IBM861 cp861 861 cp-is csIBM861 }
6083 { IBM862 cp862 862 csPC862LatinHebrew }
6084 { IBM863 cp863 863 csIBM863 }
6085 { IBM864 cp864 csIBM864 }
6086 { IBM865 cp865 865 csIBM865 }
6087 { IBM866 cp866 866 csIBM866 }
6088 { IBM868 CP868 cp-ar csIBM868 }
6089 { IBM869 cp869 869 cp-gr csIBM869 }
6090 { IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 }
6091 { IBM871 CP871 ebcdic-cp-is csIBM871 }
6092 { IBM880 cp880 EBCDIC-Cyrillic csIBM880 }
6093 { IBM891 cp891 csIBM891 }
6094 { IBM903 cp903 csIBM903 }
6095 { IBM904 cp904 904 csIBBM904 }
6096 { IBM905 CP905 ebcdic-cp-tr csIBM905 }
6097 { IBM918 CP918 ebcdic-cp-ar2 csIBM918 }
6098 { IBM1026 CP1026 csIBM1026 }
6099 { EBCDIC-AT-DE csIBMEBCDICATDE }
6100 { EBCDIC-AT-DE-A csEBCDICATDEA }
6101 { EBCDIC-CA-FR csEBCDICCAFR }
6102 { EBCDIC-DK-NO csEBCDICDKNO }
6103 { EBCDIC-DK-NO-A csEBCDICDKNOA }
6104 { EBCDIC-FI-SE csEBCDICFISE }
6105 { EBCDIC-FI-SE-A csEBCDICFISEA }
6106 { EBCDIC-FR csEBCDICFR }
6107 { EBCDIC-IT csEBCDICIT }
6108 { EBCDIC-PT csEBCDICPT }
6109 { EBCDIC-ES csEBCDICES }
6110 { EBCDIC-ES-A csEBCDICESA }
6111 { EBCDIC-ES-S csEBCDICESS }
6112 { EBCDIC-UK csEBCDICUK }
6113 { EBCDIC-US csEBCDICUS }
6114 { UNKNOWN-8BIT csUnknown8BiT }
6115 { MNEMONIC csMnemonic }
6116 { MNEM csMnem }
6117 { VISCII csVISCII }
6118 { VIQR csVIQR }
6119 { KOI8-R csKOI8R }
6120 { IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro }
6121 { IBM00924 CCSID00924 CP00924 ebcdic-Latin9--euro }
6122 { IBM01140 CCSID01140 CP01140 ebcdic-us-37+euro }
6123 { IBM01141 CCSID01141 CP01141 ebcdic-de-273+euro }
6124 { IBM01142 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro }
6125 { IBM01143 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro }
6126 { IBM01144 CCSID01144 CP01144 ebcdic-it-280+euro }
6127 { IBM01145 CCSID01145 CP01145 ebcdic-es-284+euro }
6128 { IBM01146 CCSID01146 CP01146 ebcdic-gb-285+euro }
6129 { IBM01147 CCSID01147 CP01147 ebcdic-fr-297+euro }
6130 { IBM01148 CCSID01148 CP01148 ebcdic-international-500+euro }
6131 { IBM01149 CCSID01149 CP01149 ebcdic-is-871+euro }
6132 { IBM1047 IBM-1047 }
6133 { PTCP154 csPTCP154 PT154 CP154 Cyrillic-Asian }
6134 { Amiga-1251 Ami1251 Amiga1251 Ami-1251 }
6135 { UNICODE-1-1 csUnicode11 }
6136 { CESU-8 csCESU-8 }
6137 { BOCU-1 csBOCU-1 }
6138 { UNICODE-1-1-UTF-7 csUnicode11UTF7 }
6139 { ISO-8859-14 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic
6140 l8 }
6141 { ISO-8859-15 ISO_8859-15 Latin-9 }
6142 { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
6143 { GBK CP936 MS936 windows-936 }
6144 { JIS_Encoding csJISEncoding }
6145 { Shift_JIS MS_Kanji csShiftJIS }
6146 { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
6147 EUC-JP }
6148 { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
6149 { ISO-10646-UCS-Basic csUnicodeASCII }
6150 { ISO-10646-Unicode-Latin1 csUnicodeLatin1 ISO-10646 }
6151 { ISO-Unicode-IBM-1261 csUnicodeIBM1261 }
6152 { ISO-Unicode-IBM-1268 csUnicodeIBM1268 }
6153 { ISO-Unicode-IBM-1276 csUnicodeIBM1276 }
6154 { ISO-Unicode-IBM-1264 csUnicodeIBM1264 }
6155 { ISO-Unicode-IBM-1265 csUnicodeIBM1265 }
6156 { ISO-8859-1-Windows-3.0-Latin-1 csWindows30Latin1 }
6157 { ISO-8859-1-Windows-3.1-Latin-1 csWindows31Latin1 }
6158 { ISO-8859-2-Windows-Latin-2 csWindows31Latin2 }
6159 { ISO-8859-9-Windows-Latin-5 csWindows31Latin5 }
6160 { Adobe-Standard-Encoding csAdobeStandardEncoding }
6161 { Ventura-US csVenturaUS }
6162 { Ventura-International csVenturaInternational }
6163 { PC8-Danish-Norwegian csPC8DanishNorwegian }
6164 { PC8-Turkish csPC8Turkish }
6165 { IBM-Symbols csIBMSymbols }
6166 { IBM-Thai csIBMThai }
6167 { HP-Legal csHPLegal }
6168 { HP-Pi-font csHPPiFont }
6169 { HP-Math8 csHPMath8 }
6170 { Adobe-Symbol-Encoding csHPPSMath }
6171 { HP-DeskTop csHPDesktop }
6172 { Ventura-Math csVenturaMath }
6173 { Microsoft-Publishing csMicrosoftPublishing }
6174 { Windows-31J csWindows31J }
6175 { GB2312 csGB2312 }
6176 { Big5 csBig5 }
6177}
6178
6179proc tcl_encoding {enc} {
6180 global encoding_aliases
6181 set names [encoding names]
6182 set lcnames [string tolower $names]
6183 set enc [string tolower $enc]
6184 set i [lsearch -exact $lcnames $enc]
6185 if {$i < 0} {
6186 # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
6187 if {[regsub {^iso[-_]} $enc iso encx]} {
6188 set i [lsearch -exact $lcnames $encx]
6189 }
6190 }
6191 if {$i < 0} {
6192 foreach l $encoding_aliases {
6193 set ll [string tolower $l]
6194 if {[lsearch -exact $ll $enc] < 0} continue
6195 # look through the aliases for one that tcl knows about
6196 foreach e $ll {
6197 set i [lsearch -exact $lcnames $e]
6198 if {$i < 0} {
6199 if {[regsub {^iso[-_]} $e iso ex]} {
6200 set i [lsearch -exact $lcnames $ex]
6201 }
6202 }
6203 if {$i >= 0} break
6204 }
6205 break
6206 }
6207 }
6208 if {$i >= 0} {
6209 return [lindex $names $i]
6210 }
6211 return {}
6212}
6213
Paul Mackerras1d10f362005-05-15 12:55:47 +00006214# defaults...
6215set datemode 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00006216set diffopts "-U 5 -p"
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03006217set wrcomcmd "git diff-tree --stdin -p --pretty"
Junio C Hamano671bc152005-11-27 16:12:51 -08006218
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11006219set gitencoding {}
Junio C Hamano671bc152005-11-27 16:12:51 -08006220catch {
Paul Mackerras27cb61c2007-02-15 08:54:34 +11006221 set gitencoding [exec git config --get i18n.commitencoding]
Junio C Hamano671bc152005-11-27 16:12:51 -08006222}
6223if {$gitencoding == ""} {
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11006224 set gitencoding "utf-8"
6225}
6226set tclencoding [tcl_encoding $gitencoding]
6227if {$tclencoding == {}} {
6228 puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
Junio C Hamano671bc152005-11-27 16:12:51 -08006229}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006230
6231set mainfont {Helvetica 9}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006232set textfont {Courier 9}
Keith Packard4840be62006-04-04 00:19:45 -07006233set uifont {Helvetica 9 bold}
Paul Mackerrasb74fd572005-07-16 07:46:13 -04006234set findmergefiles 0
Paul Mackerras8d858d12005-08-05 09:52:16 +10006235set maxgraphpct 50
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10006236set maxwidth 16
Paul Mackerras232475d2005-11-15 10:34:03 +11006237set revlistorder 0
Paul Mackerras757f17b2005-11-21 09:56:07 +11006238set fastdate 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11006239set uparrowlen 7
6240set downarrowlen 7
6241set mingaplen 30
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10006242set cmitmode "patch"
Sergey Vlasovf1b86292006-05-15 19:13:14 +04006243set wrapcomment "none"
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10006244set showneartags 1
Paul Mackerras1d10f362005-05-15 12:55:47 +00006245
6246set colors {green red blue magenta darkgrey brown orange}
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10006247set bgcolor white
6248set fgcolor black
6249set diffcolors {red "#00a000" blue}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006250
6251catch {source ~/.gitk}
6252
Paul Mackerras712fcc02005-11-30 09:28:16 +11006253font create optionfont -family sans-serif -size -12
Paul Mackerras17386062005-05-18 22:51:00 +00006254
Paul Mackerras1d10f362005-05-15 12:55:47 +00006255set revtreeargs {}
6256foreach arg $argv {
6257 switch -regexp -- $arg {
6258 "^$" { }
Paul Mackerras1d10f362005-05-15 12:55:47 +00006259 "^-d" { set datemode 1 }
Paul Mackerras1d10f362005-05-15 12:55:47 +00006260 default {
6261 lappend revtreeargs $arg
6262 }
6263 }
6264}
6265
Paul Mackerrasaa81d972006-02-28 11:27:12 +11006266# check that we can find a .git directory somewhere...
6267set gitdir [gitdir]
6268if {![file isdirectory $gitdir]} {
Paul Mackerrase54be9e2006-05-26 22:34:30 +10006269 show_error {} . "Cannot find the git directory \"$gitdir\"."
Paul Mackerrasaa81d972006-02-28 11:27:12 +11006270 exit 1
6271}
6272
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006273set cmdline_files {}
6274set i [lsearch -exact $revtreeargs "--"]
6275if {$i >= 0} {
6276 set cmdline_files [lrange $revtreeargs [expr {$i + 1}] end]
6277 set revtreeargs [lrange $revtreeargs 0 [expr {$i - 1}]]
6278} elseif {$revtreeargs ne {}} {
6279 if {[catch {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03006280 set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006281 set cmdline_files [split $f "\n"]
6282 set n [llength $cmdline_files]
6283 set revtreeargs [lrange $revtreeargs 0 end-$n]
6284 } err]} {
6285 # unfortunately we get both stdout and stderr in $err,
6286 # so look for "fatal:".
6287 set i [string first "fatal:" $err]
6288 if {$i > 0} {
Junio C Hamanob5e09632006-05-26 00:07:15 -07006289 set err [string range $err [expr {$i + 6}] end]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006290 }
Paul Mackerrase54be9e2006-05-26 22:34:30 +10006291 show_error {} . "Bad arguments to gitk:\n$err"
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006292 exit 1
6293 }
6294}
6295
Paul Mackerrasd6982062005-08-06 22:06:06 +10006296set history {}
6297set historyindex 0
Paul Mackerras908c3582006-05-20 09:38:11 +10006298set fh_serial 0
Paul Mackerras908c3582006-05-20 09:38:11 +10006299set nhl_names {}
Paul Mackerras63b79192006-05-20 21:31:52 +10006300set highlight_paths {}
Paul Mackerras1902c272006-05-25 21:25:13 +10006301set searchdirn -forwards
Paul Mackerras4e7d6772006-05-30 21:33:07 +10006302set boldrows {}
6303set boldnamerows {}
Paul Mackerrasd6982062005-08-06 22:06:06 +10006304
Paul Mackerras9f1afe02006-02-19 22:44:47 +11006305set optim_delay 16
6306
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006307set nextviewnum 1
6308set curview 0
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006309set selectedview 0
Paul Mackerras908c3582006-05-20 09:38:11 +10006310set selectedhlview None
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006311set viewfiles(0) {}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006312set viewperm(0) 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006313set viewargs(0) {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006314
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006315set cmdlineok 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00006316set stopped 0
Paul Mackerras0fba86b2005-05-16 23:54:58 +00006317set stuffsaved 0
Paul Mackerras74daedb2005-06-27 19:27:32 +10006318set patchnum 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00006319setcoords
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10006320makewindow
Doug Maxey6c283322006-12-10 14:31:46 -06006321wm title . "[file tail $argv0]: [file tail [pwd]]"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006322readrefs
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10006323
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006324if {$cmdline_files ne {} || $revtreeargs ne {}} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006325 # create a view for the files/dirs specified on the command line
6326 set curview 1
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006327 set selectedview 1
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006328 set nextviewnum 2
6329 set viewname(1) "Command line"
6330 set viewfiles(1) $cmdline_files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006331 set viewargs(1) $revtreeargs
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006332 set viewperm(1) 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10006333 addviewmenu 1
Paul Mackerras3cd204e2006-11-23 21:06:16 +11006334 .bar.view entryconf Edit* -state normal
6335 .bar.view entryconf Delete* -state normal
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006336}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006337
6338if {[info exists permviews]} {
6339 foreach v $permviews {
6340 set n $nextviewnum
6341 incr nextviewnum
6342 set viewname($n) [lindex $v 0]
6343 set viewfiles($n) [lindex $v 1]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006344 set viewargs($n) [lindex $v 2]
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006345 set viewperm($n) 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10006346 addviewmenu $n
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006347 }
6348}
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10006349getcommits