blob: b1c65d76806d1c26da0759569e6b83982a414bf1 [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
Mark Levedahl9ca72f42007-02-12 19:19:34 -0500442 if {![info exists geometry(pwsash0)]} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500443 set geometry(topheight) [expr {15 * $linespc}]
444 set geometry(topwidth) [expr {80 * $charspc}]
445 set geometry(botheight) [expr {15 * $linespc}]
446 set geometry(botwidth) [expr {50 * $charspc}]
Mark Levedahl9ca72f42007-02-12 19:19:34 -0500447 set geometry(pwsash0) "[expr {40 * $charspc}] 2"
448 set geometry(pwsash1) "[expr {60 * $charspc}] 2"
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000449 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500450
451 # the upper half will have a paned window, a scroll bar to the right, and some stuff below
452 frame .tf -height $geometry(topheight) -width $geometry(topwidth)
453 frame .tf.histframe
454 panedwindow .tf.histframe.pwclist -orient horizontal -sashpad 0 -handlesize 4
455
456 # create three canvases
457 set cscroll .tf.histframe.csb
458 set canv .tf.histframe.pwclist.canv
Mark Levedahl9ca72f42007-02-12 19:19:34 -0500459 canvas $canv \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000460 -background $bgcolor -bd 0 \
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100461 -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500462 .tf.histframe.pwclist add $canv
463 set canv2 .tf.histframe.pwclist.canv2
Mark Levedahl9ca72f42007-02-12 19:19:34 -0500464 canvas $canv2 \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000465 -background $bgcolor -bd 0 -yscrollincr $linespc
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500466 .tf.histframe.pwclist add $canv2
467 set canv3 .tf.histframe.pwclist.canv3
Mark Levedahl9ca72f42007-02-12 19:19:34 -0500468 canvas $canv3 \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000469 -background $bgcolor -bd 0 -yscrollincr $linespc
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500470 .tf.histframe.pwclist add $canv3
Mark Levedahl9ca72f42007-02-12 19:19:34 -0500471 eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0)
472 eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1)
Paul Mackerras98f350e2005-05-15 05:56:51 +0000473
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500474 # a scroll bar to rule them
475 scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
476 pack $cscroll -side right -fill y
477 bind .tf.histframe.pwclist <Configure> {resizeclistpanes %W %w}
478 lappend bglist $canv $canv2 $canv3
479 pack .tf.histframe.pwclist -fill both -expand 1 -side left
480
481 # we have two button bars at bottom of top frame. Bar 1
482 frame .tf.bar
483 frame .tf.lbar -height 15
484
485 set sha1entry .tf.bar.sha1
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000486 set entries $sha1entry
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500487 set sha1but .tf.bar.sha1label
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000488 button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
Keith Packard4840be62006-04-04 00:19:45 -0700489 -command gotocommit -width 8 -font $uifont
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000490 $sha1but conf -disabledforeground [$sha1but cget -foreground]
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500491 pack .tf.bar.sha1label -side left
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000492 entry $sha1entry -width 40 -font $textfont -textvariable sha1string
493 trace add variable sha1string write sha1change
Paul Mackerras98f350e2005-05-15 05:56:51 +0000494 pack $sha1entry -side left -pady 2
Paul Mackerrasd6982062005-08-06 22:06:06 +1000495
496 image create bitmap bm-left -data {
497 #define left_width 16
498 #define left_height 16
499 static unsigned char left_bits[] = {
500 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
501 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
502 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
503 }
504 image create bitmap bm-right -data {
505 #define right_width 16
506 #define right_height 16
507 static unsigned char right_bits[] = {
508 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
509 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
510 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
511 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500512 button .tf.bar.leftbut -image bm-left -command goback \
Paul Mackerrasd6982062005-08-06 22:06:06 +1000513 -state disabled -width 26
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500514 pack .tf.bar.leftbut -side left -fill y
515 button .tf.bar.rightbut -image bm-right -command goforw \
Paul Mackerrasd6982062005-08-06 22:06:06 +1000516 -state disabled -width 26
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500517 pack .tf.bar.rightbut -side left -fill y
Paul Mackerrasd6982062005-08-06 22:06:06 +1000518
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500519 button .tf.bar.findbut -text "Find" -command dofind -font $uifont
520 pack .tf.bar.findbut -side left
Paul Mackerras98f350e2005-05-15 05:56:51 +0000521 set findstring {}
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500522 set fstring .tf.bar.findstring
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000523 lappend entries $fstring
Paul Mackerras908c3582006-05-20 09:38:11 +1000524 entry $fstring -width 30 -font $textfont -textvariable findstring
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000525 trace add variable findstring write find_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500526 pack $fstring -side left -expand 1 -fill x -in .tf.bar
Paul Mackerras98f350e2005-05-15 05:56:51 +0000527 set findtype Exact
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500528 set findtypemenu [tk_optionMenu .tf.bar.findtype \
529 findtype Exact IgnCase Regexp]
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000530 trace add variable findtype write find_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500531 .tf.bar.findtype configure -font $uifont
532 .tf.bar.findtype.menu configure -font $uifont
Paul Mackerras98f350e2005-05-15 05:56:51 +0000533 set findloc "All fields"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500534 tk_optionMenu .tf.bar.findloc findloc "All fields" Headline \
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000535 Comments Author Committer
536 trace add variable findloc write find_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500537 .tf.bar.findloc configure -font $uifont
538 .tf.bar.findloc.menu configure -font $uifont
539 pack .tf.bar.findloc -side right
540 pack .tf.bar.findtype -side right
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000541
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500542 # build up the bottom bar of upper window
543 label .tf.lbar.flabel -text "Highlight: Commits " \
544 -font $uifont
545 pack .tf.lbar.flabel -side left -fill y
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000546 set gdttype "touching paths:"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500547 set gm [tk_optionMenu .tf.lbar.gdttype gdttype "touching paths:" \
548 "adding/removing string:"]
Paul Mackerras60f7a7d2006-05-26 10:43:47 +1000549 trace add variable gdttype write hfiles_change
550 $gm conf -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500551 .tf.lbar.gdttype conf -font $uifont
552 pack .tf.lbar.gdttype -side left -fill y
553 entry .tf.lbar.fent -width 25 -font $textfont \
Paul Mackerras908c3582006-05-20 09:38:11 +1000554 -textvariable highlight_files
555 trace add variable highlight_files write hfiles_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500556 lappend entries .tf.lbar.fent
557 pack .tf.lbar.fent -side left -fill x -expand 1
558 label .tf.lbar.vlabel -text " OR in view" -font $uifont
559 pack .tf.lbar.vlabel -side left -fill y
Paul Mackerras908c3582006-05-20 09:38:11 +1000560 global viewhlmenu selectedhlview
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500561 set viewhlmenu [tk_optionMenu .tf.lbar.vhl selectedhlview None]
Paul Mackerras3cd204e2006-11-23 21:06:16 +1100562 $viewhlmenu entryconf None -command delvhighlight
Paul Mackerras63b79192006-05-20 21:31:52 +1000563 $viewhlmenu conf -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500564 .tf.lbar.vhl conf -font $uifont
565 pack .tf.lbar.vhl -side left -fill y
566 label .tf.lbar.rlabel -text " OR " -font $uifont
567 pack .tf.lbar.rlabel -side left -fill y
Paul Mackerras164ff272006-05-29 19:50:02 +1000568 global highlight_related
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500569 set m [tk_optionMenu .tf.lbar.relm highlight_related None \
570 "Descendent" "Not descendent" "Ancestor" "Not ancestor"]
Paul Mackerras164ff272006-05-29 19:50:02 +1000571 $m conf -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500572 .tf.lbar.relm conf -font $uifont
Paul Mackerras164ff272006-05-29 19:50:02 +1000573 trace add variable highlight_related write vrel_change
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500574 pack .tf.lbar.relm -side left -fill y
Paul Mackerras908c3582006-05-20 09:38:11 +1000575
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500576 # Finish putting the upper half of the viewer together
577 pack .tf.lbar -in .tf -side bottom -fill x
578 pack .tf.bar -in .tf -side bottom -fill x
579 pack .tf.histframe -fill both -side top -expand 1
580 .ctop add .tf
Mark Levedahl9ca72f42007-02-12 19:19:34 -0500581 .ctop paneconfigure .tf -height $geometry(topheight)
582 .ctop paneconfigure .tf -width $geometry(topwidth)
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500583
584 # now build up the bottom
585 panedwindow .pwbottom -orient horizontal
586
587 # lower left, a text box over search bar, scroll bar to the right
588 # if we know window height, then that will set the lower text height, otherwise
589 # we set lower text height which will drive window height
590 if {[info exists geometry(main)]} {
591 frame .bleft -width $geometry(botwidth)
592 } else {
593 frame .bleft -width $geometry(botwidth) -height $geometry(botheight)
594 }
595 frame .bleft.top
596
597 button .bleft.top.search -text "Search" -command dosearch \
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000598 -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500599 pack .bleft.top.search -side left -padx 5
600 set sstring .bleft.top.sstring
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000601 entry $sstring -width 20 -font $textfont -textvariable searchstring
602 lappend entries $sstring
603 trace add variable searchstring write incrsearch
604 pack $sstring -side left -expand 1 -fill x
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500605 set ctext .bleft.ctext
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000606 text $ctext -background $bgcolor -foreground $fgcolor \
607 -state disabled -font $textfont \
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000608 -yscrollcommand scrolltext -wrap none
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500609 scrollbar .bleft.sb -command "$ctext yview"
610 pack .bleft.top -side top -fill x
611 pack .bleft.sb -side right -fill y
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000612 pack $ctext -side left -fill both -expand 1
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000613 lappend bglist $ctext
614 lappend fglist $ctext
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000615
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400616 $ctext tag conf comment -wrap $wrapcomment
Paul Mackerrasf0654862005-07-18 14:29:03 -0400617 $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000618 $ctext tag conf hunksep -fore [lindex $diffcolors 2]
619 $ctext tag conf d0 -fore [lindex $diffcolors 0]
620 $ctext tag conf d1 -fore [lindex $diffcolors 1]
Paul Mackerras712fcc02005-11-30 09:28:16 +1100621 $ctext tag conf m0 -fore red
622 $ctext tag conf m1 -fore blue
623 $ctext tag conf m2 -fore green
624 $ctext tag conf m3 -fore purple
625 $ctext tag conf m4 -fore brown
Paul Mackerrasb77b0272006-02-07 09:13:52 +1100626 $ctext tag conf m5 -fore "#009090"
627 $ctext tag conf m6 -fore magenta
628 $ctext tag conf m7 -fore "#808000"
629 $ctext tag conf m8 -fore "#009000"
630 $ctext tag conf m9 -fore "#ff0080"
631 $ctext tag conf m10 -fore cyan
632 $ctext tag conf m11 -fore "#b07070"
633 $ctext tag conf m12 -fore "#70b0f0"
634 $ctext tag conf m13 -fore "#70f0b0"
635 $ctext tag conf m14 -fore "#f0b070"
636 $ctext tag conf m15 -fore "#ff70b0"
Paul Mackerras712fcc02005-11-30 09:28:16 +1100637 $ctext tag conf mmax -fore darkgrey
Paul Mackerrasb77b0272006-02-07 09:13:52 +1100638 set mergemax 16
Paul Mackerras712fcc02005-11-30 09:28:16 +1100639 $ctext tag conf mresult -font [concat $textfont bold]
640 $ctext tag conf msep -font [concat $textfont bold]
641 $ctext tag conf found -back yellow
Paul Mackerrase5c2d852005-05-11 23:44:54 +0000642
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500643 .pwbottom add .bleft
Mark Levedahl9ca72f42007-02-12 19:19:34 -0500644 .pwbottom paneconfigure .bleft -width $geometry(botwidth)
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500645
646 # lower right
647 frame .bright
648 frame .bright.mode
649 radiobutton .bright.mode.patch -text "Patch" \
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000650 -command reselectline -variable cmitmode -value "patch"
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +0400651 .bright.mode.patch configure -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500652 radiobutton .bright.mode.tree -text "Tree" \
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000653 -command reselectline -variable cmitmode -value "tree"
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +0400654 .bright.mode.tree configure -font $uifont
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500655 grid .bright.mode.patch .bright.mode.tree -sticky ew
656 pack .bright.mode -side top -fill x
657 set cflist .bright.cfiles
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000658 set indent [font measure $mainfont "nn"]
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500659 text $cflist \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000660 -background $bgcolor -foreground $fgcolor \
661 -font $mainfont \
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000662 -tabs [list $indent [expr {2 * $indent}]] \
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500663 -yscrollcommand ".bright.sb set" \
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000664 -cursor [. cget -cursor] \
665 -spacing1 1 -spacing3 1
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000666 lappend bglist $cflist
667 lappend fglist $cflist
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500668 scrollbar .bright.sb -command "$cflist yview"
669 pack .bright.sb -side right -fill y
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000670 pack $cflist -side left -fill both -expand 1
Paul Mackerras89b11d32006-05-02 19:55:31 +1000671 $cflist tag configure highlight \
672 -background [$cflist cget -selectbackground]
Paul Mackerras63b79192006-05-20 21:31:52 +1000673 $cflist tag configure bold -font [concat $mainfont bold]
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000674
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500675 .pwbottom add .bright
676 .ctop add .pwbottom
Paul Mackerras1db95b02005-05-09 04:08:39 +0000677
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500678 # restore window position if known
679 if {[info exists geometry(main)]} {
680 wm geometry . "$geometry(main)"
681 }
682
683 bind .pwbottom <Configure> {resizecdetpanes %W %w}
684 pack .ctop -fill both -expand 1
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000685 bindall <1> {selcanvline %W %x %y}
686 #bindall <B1-Motion> {selcanvline %W %x %y}
Paul Mackerrascfb45632005-05-31 12:14:42 +0000687 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
688 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
Paul Mackerrasbe0cd092006-03-31 09:55:11 +1100689 bindall <2> "canvscan mark %W %x %y"
690 bindall <B2-Motion> "canvscan dragto %W %x %y"
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000691 bindkey <Home> selfirstline
692 bindkey <End> sellastline
Paul Mackerras17386062005-05-18 22:51:00 +0000693 bind . <Key-Up> "selnextline -1"
694 bind . <Key-Down> "selnextline 1"
Paul Mackerras4e7d6772006-05-30 21:33:07 +1000695 bind . <Shift-Key-Up> "next_highlight -1"
696 bind . <Shift-Key-Down> "next_highlight 1"
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000697 bindkey <Key-Right> "goforw"
698 bindkey <Key-Left> "goback"
699 bind . <Key-Prior> "selnextpage -1"
700 bind . <Key-Next> "selnextpage 1"
701 bind . <Control-Home> "allcanvs yview moveto 0.0"
702 bind . <Control-End> "allcanvs yview moveto 1.0"
703 bind . <Control-Key-Up> "allcanvs yview scroll -1 units"
704 bind . <Control-Key-Down> "allcanvs yview scroll 1 units"
705 bind . <Control-Key-Prior> "allcanvs yview scroll -1 pages"
706 bind . <Control-Key-Next> "allcanvs yview scroll 1 pages"
Paul Mackerrascfb45632005-05-31 12:14:42 +0000707 bindkey <Key-Delete> "$ctext yview scroll -1 pages"
708 bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
709 bindkey <Key-space> "$ctext yview scroll 1 pages"
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000710 bindkey p "selnextline -1"
711 bindkey n "selnextline 1"
Robert Suetterlin6e2dda32005-09-22 10:07:36 +1000712 bindkey z "goback"
713 bindkey x "goforw"
714 bindkey i "selnextline -1"
715 bindkey k "selnextline 1"
716 bindkey j "goback"
717 bindkey l "goforw"
Paul Mackerrascfb45632005-05-31 12:14:42 +0000718 bindkey b "$ctext yview scroll -1 pages"
719 bindkey d "$ctext yview scroll 18 units"
720 bindkey u "$ctext yview scroll -18 units"
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400721 bindkey / {findnext 1}
722 bindkey <Key-Return> {findnext 0}
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000723 bindkey ? findprev
Paul Mackerras39ad8572005-05-19 12:35:53 +0000724 bindkey f nextfile
Eric Wonge7a09192007-02-23 12:36:34 -0800725 bindkey <F5> updatecommits
Paul Mackerras1d10f362005-05-15 12:55:47 +0000726 bind . <Control-q> doquit
Paul Mackerras98f350e2005-05-15 05:56:51 +0000727 bind . <Control-f> dofind
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400728 bind . <Control-g> {findnext 0}
Paul Mackerras1902c272006-05-25 21:25:13 +1000729 bind . <Control-r> dosearchback
Paul Mackerras3ea06f92006-05-24 10:16:03 +1000730 bind . <Control-s> dosearch
Paul Mackerras1d10f362005-05-15 12:55:47 +0000731 bind . <Control-equal> {incrfont 1}
732 bind . <Control-KP_Add> {incrfont 1}
733 bind . <Control-minus> {incrfont -1}
734 bind . <Control-KP_Subtract> {incrfont -1}
Mark Levedahlb6047c52007-02-08 22:22:24 -0500735 wm protocol . WM_DELETE_WINDOW doquit
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000736 bind . <Button-1> "click %W"
Paul Mackerras17386062005-05-18 22:51:00 +0000737 bind $fstring <Key-Return> dofind
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000738 bind $sha1entry <Key-Return> gotocommit
Paul Mackerrasee3dc722005-06-25 16:37:13 +1000739 bind $sha1entry <<PasteSelection>> clearsha1
Paul Mackerras7fcceed2006-04-27 19:21:49 +1000740 bind $cflist <1> {sel_flist %W %x %y; break}
741 bind $cflist <B1-Motion> {sel_flist %W %x %y; break}
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000742 bind $cflist <ButtonRelease-1> {treeclick %W %x %y}
Paul Mackerrasea13cba2005-06-16 10:54:04 +0000743
744 set maincursor [. cget -cursor]
745 set textcursor [$ctext cget -cursor]
Paul Mackerras94a2eed2005-08-07 15:27:57 +1000746 set curtextcursor $textcursor
Paul Mackerras84ba7342005-06-17 00:12:26 +0000747
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000748 set rowctxmenu .rowctxmenu
749 menu $rowctxmenu -tearoff 0
750 $rowctxmenu add command -label "Diff this -> selected" \
751 -command {diffvssel 0}
752 $rowctxmenu add command -label "Diff selected -> this" \
753 -command {diffvssel 1}
Paul Mackerras74daedb2005-06-27 19:27:32 +1000754 $rowctxmenu add command -label "Make patch" -command mkpatch
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +1000755 $rowctxmenu add command -label "Create tag" -command mktag
Paul Mackerras4a2139f2005-06-29 09:47:48 +1000756 $rowctxmenu add command -label "Write commit to file" -command writecommit
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +1000757 $rowctxmenu add command -label "Create new branch" -command mkbranch
Paul Mackerrasca6d8f52006-08-06 21:08:05 +1000758 $rowctxmenu add command -label "Cherry-pick this commit" \
759 -command cherrypick
Paul Mackerras10299152006-08-02 09:52:01 +1000760
761 set headctxmenu .headctxmenu
762 menu $headctxmenu -tearoff 0
763 $headctxmenu add command -label "Check out this branch" \
764 -command cobranch
765 $headctxmenu add command -label "Remove this branch" \
766 -command rmbranch
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000767}
768
Paul Mackerrasbe0cd092006-03-31 09:55:11 +1100769# mouse-2 makes all windows scan vertically, but only the one
770# the cursor is in scans horizontally
771proc canvscan {op w x y} {
772 global canv canv2 canv3
773 foreach c [list $canv $canv2 $canv3] {
774 if {$c == $w} {
775 $c scan $op $x $y
776 } else {
777 $c scan $op 0 $y
778 }
779 }
780}
781
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100782proc scrollcanv {cscroll f0 f1} {
783 $cscroll set $f0 $f1
784 drawfrac $f0 $f1
Paul Mackerras908c3582006-05-20 09:38:11 +1000785 flushhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100786}
787
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000788# when we make a key binding for the toplevel, make sure
789# it doesn't get triggered when that key is pressed in the
790# find string entry widget.
791proc bindkey {ev script} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000792 global entries
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000793 bind . $ev $script
794 set escript [bind Entry $ev]
795 if {$escript == {}} {
796 set escript [bind Entry <Key>]
797 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000798 foreach e $entries {
799 bind $e $ev "$escript; break"
800 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000801}
802
803# set the focus back to the toplevel for any click outside
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000804# the entry widgets
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000805proc click {w} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000806 global entries
807 foreach e $entries {
808 if {$w == $e} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000809 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000810 focus .
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000811}
812
813proc savestuff {w} {
Keith Packard4840be62006-04-04 00:19:45 -0700814 global canv canv2 canv3 ctext cflist mainfont textfont uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +1100815 global stuffsaved findmergefiles maxgraphpct
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +1000816 global maxwidth showneartags
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000817 global viewname viewfiles viewargs viewperm nextviewnum
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400818 global cmitmode wrapcomment
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000819 global colors bgcolor fgcolor diffcolors
Paul Mackerras4ef17532005-07-27 22:16:51 -0500820
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000821 if {$stuffsaved} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000822 if {![winfo viewable .]} return
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000823 catch {
824 set f [open "~/.gitk-new" w]
Paul Mackerrasf0654862005-07-18 14:29:03 -0400825 puts $f [list set mainfont $mainfont]
826 puts $f [list set textfont $textfont]
Keith Packard4840be62006-04-04 00:19:45 -0700827 puts $f [list set uifont $uifont]
Paul Mackerrasf0654862005-07-18 14:29:03 -0400828 puts $f [list set findmergefiles $findmergefiles]
Paul Mackerras8d858d12005-08-05 09:52:16 +1000829 puts $f [list set maxgraphpct $maxgraphpct]
Paul Mackerras04c13d32005-08-19 10:22:24 +1000830 puts $f [list set maxwidth $maxwidth]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +1000831 puts $f [list set cmitmode $cmitmode]
Sergey Vlasovf1b86292006-05-15 19:13:14 +0400832 puts $f [list set wrapcomment $wrapcomment]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +1000833 puts $f [list set showneartags $showneartags]
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +1000834 puts $f [list set bgcolor $bgcolor]
835 puts $f [list set fgcolor $fgcolor]
836 puts $f [list set colors $colors]
837 puts $f [list set diffcolors $diffcolors]
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500838
Mark Levedahlb6047c52007-02-08 22:22:24 -0500839 puts $f "set geometry(main) [wm geometry .]"
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500840 puts $f "set geometry(topwidth) [winfo width .tf]"
841 puts $f "set geometry(topheight) [winfo height .tf]"
Mark Levedahl9ca72f42007-02-12 19:19:34 -0500842 puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\""
843 puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\""
Junio C Hamanoe9937d22007-02-01 08:46:38 -0500844 puts $f "set geometry(botwidth) [winfo width .bleft]"
845 puts $f "set geometry(botheight) [winfo height .bleft]"
846
Paul Mackerrasa90a6d22006-04-25 17:12:46 +1000847 puts -nonewline $f "set permviews {"
848 for {set v 0} {$v < $nextviewnum} {incr v} {
849 if {$viewperm($v)} {
Paul Mackerras098dd8a2006-05-03 09:32:53 +1000850 puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v)]}"
Paul Mackerrasa90a6d22006-04-25 17:12:46 +1000851 }
852 }
853 puts $f "}"
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000854 close $f
855 file rename -force "~/.gitk-new" "~/.gitk"
856 }
857 set stuffsaved 1
Paul Mackerras1db95b02005-05-09 04:08:39 +0000858}
859
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000860proc resizeclistpanes {win w} {
861 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +1100862 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000863 set s0 [$win sash coord 0]
864 set s1 [$win sash coord 1]
865 if {$w < 60} {
866 set sash0 [expr {int($w/2 - 2)}]
867 set sash1 [expr {int($w*5/6 - 2)}]
868 } else {
869 set factor [expr {1.0 * $w / $oldwidth($win)}]
870 set sash0 [expr {int($factor * [lindex $s0 0])}]
871 set sash1 [expr {int($factor * [lindex $s1 0])}]
872 if {$sash0 < 30} {
873 set sash0 30
874 }
875 if {$sash1 < $sash0 + 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800876 set sash1 [expr {$sash0 + 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000877 }
878 if {$sash1 > $w - 10} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800879 set sash1 [expr {$w - 10}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000880 if {$sash0 > $sash1 - 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800881 set sash0 [expr {$sash1 - 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000882 }
883 }
884 }
885 $win sash place 0 $sash0 [lindex $s0 1]
886 $win sash place 1 $sash1 [lindex $s1 1]
887 }
888 set oldwidth($win) $w
889}
890
891proc resizecdetpanes {win w} {
892 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +1100893 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000894 set s0 [$win sash coord 0]
895 if {$w < 60} {
896 set sash0 [expr {int($w*3/4 - 2)}]
897 } else {
898 set factor [expr {1.0 * $w / $oldwidth($win)}]
899 set sash0 [expr {int($factor * [lindex $s0 0])}]
900 if {$sash0 < 45} {
901 set sash0 45
902 }
903 if {$sash0 > $w - 15} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800904 set sash0 [expr {$w - 15}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000905 }
906 }
907 $win sash place 0 $sash0 [lindex $s0 1]
908 }
909 set oldwidth($win) $w
910}
911
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000912proc allcanvs args {
913 global canv canv2 canv3
914 eval $canv $args
915 eval $canv2 $args
916 eval $canv3 $args
917}
918
919proc bindall {event action} {
920 global canv canv2 canv3
921 bind $canv $event $action
922 bind $canv2 $event $action
923 bind $canv3 $event $action
924}
925
Paul Mackerras9a40c502005-05-12 23:46:16 +0000926proc about {} {
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +0400927 global uifont
Paul Mackerras9a40c502005-05-12 23:46:16 +0000928 set w .about
929 if {[winfo exists $w]} {
930 raise $w
931 return
932 }
933 toplevel $w
934 wm title $w "About gitk"
935 message $w.m -text {
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100936Gitk - a commit viewer for git
Paul Mackerras9a40c502005-05-12 23:46:16 +0000937
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100938Copyright © 2005-2006 Paul Mackerras
Paul Mackerras9a40c502005-05-12 23:46:16 +0000939
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000940Use and redistribute under the terms of the GNU General Public License} \
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +0400941 -justify center -aspect 400 -border 2 -bg white -relief groove
942 pack $w.m -side top -fill x -padx 2 -pady 2
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +0400943 $w.m configure -font $uifont
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +0400944 button $w.ok -text Close -command "destroy $w" -default active
Paul Mackerras9a40c502005-05-12 23:46:16 +0000945 pack $w.ok -side bottom
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +0400946 $w.ok configure -font $uifont
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +0400947 bind $w <Visibility> "focus $w.ok"
948 bind $w <Key-Escape> "destroy $w"
949 bind $w <Key-Return> "destroy $w"
Paul Mackerras9a40c502005-05-12 23:46:16 +0000950}
951
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000952proc keys {} {
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +0400953 global uifont
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000954 set w .keys
955 if {[winfo exists $w]} {
956 raise $w
957 return
958 }
959 toplevel $w
960 wm title $w "Gitk key bindings"
961 message $w.m -text {
962Gitk key bindings:
963
964<Ctrl-Q> Quit
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000965<Home> Move to first commit
966<End> Move to last commit
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000967<Up>, p, i Move up one commit
968<Down>, n, k Move down one commit
969<Left>, z, j Go back in history list
970<Right>, x, l Go forward in history list
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +1000971<PageUp> Move up one page in commit list
972<PageDown> Move down one page in commit list
973<Ctrl-Home> Scroll to top of commit list
974<Ctrl-End> Scroll to bottom of commit list
975<Ctrl-Up> Scroll commit list up one line
976<Ctrl-Down> Scroll commit list down one line
977<Ctrl-PageUp> Scroll commit list up one page
978<Ctrl-PageDown> Scroll commit list down one page
Paul Mackerras4e7d6772006-05-30 21:33:07 +1000979<Shift-Up> Move to previous highlighted line
980<Shift-Down> Move to next highlighted line
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000981<Delete>, b Scroll diff view up one page
982<Backspace> Scroll diff view up one page
983<Space> Scroll diff view down one page
984u Scroll diff view up 18 lines
985d Scroll diff view down 18 lines
986<Ctrl-F> Find
987<Ctrl-G> Move to next find hit
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000988<Return> Move to next find hit
989/ Move to next find hit, or redo find
990? Move to previous find hit
991f Scroll diff view to next file
Paul Mackerras4e7d6772006-05-30 21:33:07 +1000992<Ctrl-S> Search for next hit in diff view
993<Ctrl-R> Search for previous hit in diff view
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000994<Ctrl-KP+> Increase font size
995<Ctrl-plus> Increase font size
996<Ctrl-KP-> Decrease font size
997<Ctrl-minus> Decrease font size
Eric Wonge7a09192007-02-23 12:36:34 -0800998<F5> Update
Paul Mackerras4e95e1f2006-04-05 09:39:51 +1000999} \
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04001000 -justify left -bg white -border 2 -relief groove
1001 pack $w.m -side top -fill both -padx 2 -pady 2
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04001002 $w.m configure -font $uifont
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04001003 button $w.ok -text Close -command "destroy $w" -default active
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10001004 pack $w.ok -side bottom
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04001005 $w.ok configure -font $uifont
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04001006 bind $w <Visibility> "focus $w.ok"
1007 bind $w <Key-Escape> "destroy $w"
1008 bind $w <Key-Return> "destroy $w"
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10001009}
1010
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001011# Procedures for manipulating the file list window at the
1012# bottom right of the overall window.
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001013
1014proc treeview {w l openlevs} {
1015 global treecontents treediropen treeheight treeparent treeindex
1016
1017 set ix 0
1018 set treeindex() 0
1019 set lev 0
1020 set prefix {}
1021 set prefixend -1
1022 set prefendstack {}
1023 set htstack {}
1024 set ht 0
1025 set treecontents() {}
1026 $w conf -state normal
1027 foreach f $l {
1028 while {[string range $f 0 $prefixend] ne $prefix} {
1029 if {$lev <= $openlevs} {
1030 $w mark set e:$treeindex($prefix) "end -1c"
1031 $w mark gravity e:$treeindex($prefix) left
1032 }
1033 set treeheight($prefix) $ht
1034 incr ht [lindex $htstack end]
1035 set htstack [lreplace $htstack end end]
1036 set prefixend [lindex $prefendstack end]
1037 set prefendstack [lreplace $prefendstack end end]
1038 set prefix [string range $prefix 0 $prefixend]
1039 incr lev -1
1040 }
1041 set tail [string range $f [expr {$prefixend+1}] end]
1042 while {[set slash [string first "/" $tail]] >= 0} {
1043 lappend htstack $ht
1044 set ht 0
1045 lappend prefendstack $prefixend
1046 incr prefixend [expr {$slash + 1}]
1047 set d [string range $tail 0 $slash]
1048 lappend treecontents($prefix) $d
1049 set oldprefix $prefix
1050 append prefix $d
1051 set treecontents($prefix) {}
1052 set treeindex($prefix) [incr ix]
1053 set treeparent($prefix) $oldprefix
1054 set tail [string range $tail [expr {$slash+1}] end]
1055 if {$lev <= $openlevs} {
1056 set ht 1
1057 set treediropen($prefix) [expr {$lev < $openlevs}]
1058 set bm [expr {$lev == $openlevs? "tri-rt": "tri-dn"}]
1059 $w mark set d:$ix "end -1c"
1060 $w mark gravity d:$ix left
1061 set str "\n"
1062 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
1063 $w insert end $str
1064 $w image create end -align center -image $bm -padx 1 \
1065 -name a:$ix
Paul Mackerras45a9d502006-05-20 22:56:27 +10001066 $w insert end $d [highlight_tag $prefix]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001067 $w mark set s:$ix "end -1c"
1068 $w mark gravity s:$ix left
1069 }
1070 incr lev
1071 }
1072 if {$tail ne {}} {
1073 if {$lev <= $openlevs} {
1074 incr ht
1075 set str "\n"
1076 for {set i 0} {$i < $lev} {incr i} {append str "\t"}
1077 $w insert end $str
Paul Mackerras45a9d502006-05-20 22:56:27 +10001078 $w insert end $tail [highlight_tag $f]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001079 }
1080 lappend treecontents($prefix) $tail
1081 }
1082 }
1083 while {$htstack ne {}} {
1084 set treeheight($prefix) $ht
1085 incr ht [lindex $htstack end]
1086 set htstack [lreplace $htstack end end]
1087 }
1088 $w conf -state disabled
1089}
1090
1091proc linetoelt {l} {
1092 global treeheight treecontents
1093
1094 set y 2
1095 set prefix {}
1096 while {1} {
1097 foreach e $treecontents($prefix) {
1098 if {$y == $l} {
1099 return "$prefix$e"
1100 }
1101 set n 1
1102 if {[string index $e end] eq "/"} {
1103 set n $treeheight($prefix$e)
1104 if {$y + $n > $l} {
1105 append prefix $e
1106 incr y
1107 break
1108 }
1109 }
1110 incr y $n
1111 }
1112 }
1113}
1114
Paul Mackerras45a9d502006-05-20 22:56:27 +10001115proc highlight_tree {y prefix} {
1116 global treeheight treecontents cflist
1117
1118 foreach e $treecontents($prefix) {
1119 set path $prefix$e
1120 if {[highlight_tag $path] ne {}} {
1121 $cflist tag add bold $y.0 "$y.0 lineend"
1122 }
1123 incr y
1124 if {[string index $e end] eq "/" && $treeheight($path) > 1} {
1125 set y [highlight_tree $y $path]
1126 }
1127 }
1128 return $y
1129}
1130
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001131proc treeclosedir {w dir} {
1132 global treediropen treeheight treeparent treeindex
1133
1134 set ix $treeindex($dir)
1135 $w conf -state normal
1136 $w delete s:$ix e:$ix
1137 set treediropen($dir) 0
1138 $w image configure a:$ix -image tri-rt
1139 $w conf -state disabled
1140 set n [expr {1 - $treeheight($dir)}]
1141 while {$dir ne {}} {
1142 incr treeheight($dir) $n
1143 set dir $treeparent($dir)
1144 }
1145}
1146
1147proc treeopendir {w dir} {
1148 global treediropen treeheight treeparent treecontents treeindex
1149
1150 set ix $treeindex($dir)
1151 $w conf -state normal
1152 $w image configure a:$ix -image tri-dn
1153 $w mark set e:$ix s:$ix
1154 $w mark gravity e:$ix right
1155 set lev 0
1156 set str "\n"
1157 set n [llength $treecontents($dir)]
1158 for {set x $dir} {$x ne {}} {set x $treeparent($x)} {
1159 incr lev
1160 append str "\t"
1161 incr treeheight($x) $n
1162 }
1163 foreach e $treecontents($dir) {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001164 set de $dir$e
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001165 if {[string index $e end] eq "/"} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001166 set iy $treeindex($de)
1167 $w mark set d:$iy e:$ix
1168 $w mark gravity d:$iy left
1169 $w insert e:$ix $str
1170 set treediropen($de) 0
1171 $w image create e:$ix -align center -image tri-rt -padx 1 \
1172 -name a:$iy
Paul Mackerras45a9d502006-05-20 22:56:27 +10001173 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001174 $w mark set s:$iy e:$ix
1175 $w mark gravity s:$iy left
1176 set treeheight($de) 1
1177 } else {
1178 $w insert e:$ix $str
Paul Mackerras45a9d502006-05-20 22:56:27 +10001179 $w insert e:$ix $e [highlight_tag $de]
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001180 }
1181 }
1182 $w mark gravity e:$ix left
1183 $w conf -state disabled
1184 set treediropen($dir) 1
1185 set top [lindex [split [$w index @0,0] .] 0]
1186 set ht [$w cget -height]
1187 set l [lindex [split [$w index s:$ix] .] 0]
1188 if {$l < $top} {
1189 $w yview $l.0
1190 } elseif {$l + $n + 1 > $top + $ht} {
1191 set top [expr {$l + $n + 2 - $ht}]
1192 if {$l < $top} {
1193 set top $l
1194 }
1195 $w yview $top.0
1196 }
1197}
1198
1199proc treeclick {w x y} {
1200 global treediropen cmitmode ctext cflist cflist_top
1201
1202 if {$cmitmode ne "tree"} return
1203 if {![info exists cflist_top]} return
1204 set l [lindex [split [$w index "@$x,$y"] "."] 0]
1205 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
1206 $cflist tag add highlight $l.0 "$l.0 lineend"
1207 set cflist_top $l
1208 if {$l == 1} {
1209 $ctext yview 1.0
1210 return
1211 }
1212 set e [linetoelt $l]
1213 if {[string index $e end] ne "/"} {
1214 showfile $e
1215 } elseif {$treediropen($e)} {
1216 treeclosedir $w $e
1217 } else {
1218 treeopendir $w $e
1219 }
1220}
1221
1222proc setfilelist {id} {
1223 global treefilelist cflist
1224
1225 treeview $cflist $treefilelist($id) 0
1226}
1227
1228image create bitmap tri-rt -background black -foreground blue -data {
1229 #define tri-rt_width 13
1230 #define tri-rt_height 13
1231 static unsigned char tri-rt_bits[] = {
1232 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x70, 0x00, 0xf0, 0x00,
1233 0xf0, 0x01, 0xf0, 0x00, 0x70, 0x00, 0x30, 0x00, 0x10, 0x00, 0x00, 0x00,
1234 0x00, 0x00};
1235} -maskdata {
1236 #define tri-rt-mask_width 13
1237 #define tri-rt-mask_height 13
1238 static unsigned char tri-rt-mask_bits[] = {
1239 0x08, 0x00, 0x18, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf8, 0x00, 0xf8, 0x01,
1240 0xf8, 0x03, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0x38, 0x00, 0x18, 0x00,
1241 0x08, 0x00};
1242}
1243image create bitmap tri-dn -background black -foreground blue -data {
1244 #define tri-dn_width 13
1245 #define tri-dn_height 13
1246 static unsigned char tri-dn_bits[] = {
1247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xf8, 0x03,
1248 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00};
1250} -maskdata {
1251 #define tri-dn-mask_width 13
1252 #define tri-dn-mask_height 13
1253 static unsigned char tri-dn-mask_bits[] = {
1254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0xfe, 0x0f, 0xfc, 0x07,
1255 0xf8, 0x03, 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
1256 0x00, 0x00};
1257}
1258
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001259proc init_flist {first} {
Paul Mackerras89b11d32006-05-02 19:55:31 +10001260 global cflist cflist_top selectedline difffilestart
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001261
1262 $cflist conf -state normal
1263 $cflist delete 0.0 end
1264 if {$first ne {}} {
1265 $cflist insert end $first
1266 set cflist_top 1
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001267 $cflist tag add highlight 1.0 "1.0 lineend"
1268 } else {
1269 catch {unset cflist_top}
1270 }
1271 $cflist conf -state disabled
1272 set difffilestart {}
1273}
1274
Paul Mackerras63b79192006-05-20 21:31:52 +10001275proc highlight_tag {f} {
1276 global highlight_paths
1277
1278 foreach p $highlight_paths {
1279 if {[string match $p $f]} {
1280 return "bold"
1281 }
1282 }
1283 return {}
1284}
1285
1286proc highlight_filelist {} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001287 global cmitmode cflist
Paul Mackerras63b79192006-05-20 21:31:52 +10001288
Paul Mackerras45a9d502006-05-20 22:56:27 +10001289 $cflist conf -state normal
1290 if {$cmitmode ne "tree"} {
Paul Mackerras63b79192006-05-20 21:31:52 +10001291 set end [lindex [split [$cflist index end] .] 0]
1292 for {set l 2} {$l < $end} {incr l} {
1293 set line [$cflist get $l.0 "$l.0 lineend"]
1294 if {[highlight_tag $line] ne {}} {
1295 $cflist tag add bold $l.0 "$l.0 lineend"
1296 }
1297 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10001298 } else {
1299 highlight_tree 2 {}
Paul Mackerras63b79192006-05-20 21:31:52 +10001300 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10001301 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 21:31:52 +10001302}
1303
1304proc unhighlight_filelist {} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001305 global cflist
Paul Mackerras63b79192006-05-20 21:31:52 +10001306
Paul Mackerras45a9d502006-05-20 22:56:27 +10001307 $cflist conf -state normal
1308 $cflist tag remove bold 1.0 end
1309 $cflist conf -state disabled
Paul Mackerras63b79192006-05-20 21:31:52 +10001310}
1311
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001312proc add_flist {fl} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001313 global cflist
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001314
Paul Mackerras45a9d502006-05-20 22:56:27 +10001315 $cflist conf -state normal
1316 foreach f $fl {
1317 $cflist insert end "\n"
1318 $cflist insert end $f [highlight_tag $f]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001319 }
Paul Mackerras45a9d502006-05-20 22:56:27 +10001320 $cflist conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001321}
1322
1323proc sel_flist {w x y} {
Paul Mackerras45a9d502006-05-20 22:56:27 +10001324 global ctext difffilestart cflist cflist_top cmitmode
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001325
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001326 if {$cmitmode eq "tree"} return
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001327 if {![info exists cflist_top]} return
1328 set l [lindex [split [$w index "@$x,$y"] "."] 0]
Paul Mackerras89b11d32006-05-02 19:55:31 +10001329 $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
1330 $cflist tag add highlight $l.0 "$l.0 lineend"
1331 set cflist_top $l
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10001332 if {$l == 1} {
1333 $ctext yview 1.0
1334 } else {
1335 catch {$ctext yview [lindex $difffilestart [expr {$l - 2}]]}
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001336 }
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001337}
1338
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001339# Functions for adding and removing shell-type quoting
1340
1341proc shellquote {str} {
1342 if {![string match "*\['\"\\ \t]*" $str]} {
1343 return $str
1344 }
1345 if {![string match "*\['\"\\]*" $str]} {
1346 return "\"$str\""
1347 }
1348 if {![string match "*'*" $str]} {
1349 return "'$str'"
1350 }
1351 return "\"[string map {\" \\\" \\ \\\\} $str]\""
1352}
1353
1354proc shellarglist {l} {
1355 set str {}
1356 foreach a $l {
1357 if {$str ne {}} {
1358 append str " "
1359 }
1360 append str [shellquote $a]
1361 }
1362 return $str
1363}
1364
1365proc shelldequote {str} {
1366 set ret {}
1367 set used -1
1368 while {1} {
1369 incr used
1370 if {![regexp -start $used -indices "\['\"\\\\ \t]" $str first]} {
1371 append ret [string range $str $used end]
1372 set used [string length $str]
1373 break
1374 }
1375 set first [lindex $first 0]
1376 set ch [string index $str $first]
1377 if {$first > $used} {
1378 append ret [string range $str $used [expr {$first - 1}]]
1379 set used $first
1380 }
1381 if {$ch eq " " || $ch eq "\t"} break
1382 incr used
1383 if {$ch eq "'"} {
1384 set first [string first "'" $str $used]
1385 if {$first < 0} {
1386 error "unmatched single-quote"
1387 }
1388 append ret [string range $str $used [expr {$first - 1}]]
1389 set used $first
1390 continue
1391 }
1392 if {$ch eq "\\"} {
1393 if {$used >= [string length $str]} {
1394 error "trailing backslash"
1395 }
1396 append ret [string index $str $used]
1397 continue
1398 }
1399 # here ch == "\""
1400 while {1} {
1401 if {![regexp -start $used -indices "\[\"\\\\]" $str first]} {
1402 error "unmatched double-quote"
1403 }
1404 set first [lindex $first 0]
1405 set ch [string index $str $first]
1406 if {$first > $used} {
1407 append ret [string range $str $used [expr {$first - 1}]]
1408 set used $first
1409 }
1410 if {$ch eq "\""} break
1411 incr used
1412 append ret [string index $str $used]
1413 incr used
1414 }
1415 }
1416 return [list $used $ret]
1417}
1418
1419proc shellsplit {str} {
1420 set l {}
1421 while {1} {
1422 set str [string trimleft $str]
1423 if {$str eq {}} break
1424 set dq [shelldequote $str]
1425 set n [lindex $dq 0]
1426 set word [lindex $dq 1]
1427 set str [string range $str $n end]
1428 lappend l $word
1429 }
1430 return $l
1431}
1432
Paul Mackerras7fcceed2006-04-27 19:21:49 +10001433# Code to implement multiple views
1434
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001435proc newview {ishighlight} {
1436 global nextviewnum newviewname newviewperm uifont newishighlight
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001437 global newviewargs revtreeargs
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001438
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001439 set newishighlight $ishighlight
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001440 set top .gitkview
1441 if {[winfo exists $top]} {
1442 raise $top
1443 return
1444 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001445 set newviewname($nextviewnum) "View $nextviewnum"
1446 set newviewperm($nextviewnum) 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001447 set newviewargs($nextviewnum) [shellarglist $revtreeargs]
Mark Levedahl40b87ff2007-02-01 08:44:46 -05001448 vieweditor $top $nextviewnum "Gitk view definition"
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001449}
1450
1451proc editview {} {
1452 global curview
1453 global viewname viewperm newviewname newviewperm
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001454 global viewargs newviewargs
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001455
1456 set top .gitkvedit-$curview
1457 if {[winfo exists $top]} {
1458 raise $top
1459 return
1460 }
1461 set newviewname($curview) $viewname($curview)
1462 set newviewperm($curview) $viewperm($curview)
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001463 set newviewargs($curview) [shellarglist $viewargs($curview)]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001464 vieweditor $top $curview "Gitk: edit view $viewname($curview)"
1465}
1466
1467proc vieweditor {top n title} {
1468 global newviewname newviewperm viewfiles
1469 global uifont
1470
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001471 toplevel $top
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001472 wm title $top $title
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001473 label $top.nl -text "Name" -font $uifont
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04001474 entry $top.name -width 20 -textvariable newviewname($n) -font $uifont
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001475 grid $top.nl $top.name -sticky w -pady 5
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04001476 checkbutton $top.perm -text "Remember this view" -variable newviewperm($n) \
1477 -font $uifont
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001478 grid $top.perm - -pady 5 -sticky w
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001479 message $top.al -aspect 1000 -font $uifont \
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03001480 -text "Commits to include (arguments to git rev-list):"
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001481 grid $top.al - -sticky w -pady 5
1482 entry $top.args -width 50 -textvariable newviewargs($n) \
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04001483 -background white -font $uifont
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001484 grid $top.args - -sticky ew -padx 5
1485 message $top.l -aspect 1000 -font $uifont \
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001486 -text "Enter files and directories to include, one per line:"
1487 grid $top.l - -sticky w
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04001488 text $top.t -width 40 -height 10 -background white -font $uifont
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001489 if {[info exists viewfiles($n)]} {
1490 foreach f $viewfiles($n) {
1491 $top.t insert end $f
1492 $top.t insert end "\n"
1493 }
1494 $top.t delete {end - 1c} end
1495 $top.t mark set insert 0.0
1496 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001497 grid $top.t - -sticky ew -padx 5
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001498 frame $top.buts
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04001499 button $top.buts.ok -text "OK" -command [list newviewok $top $n] \
1500 -font $uifont
1501 button $top.buts.can -text "Cancel" -command [list destroy $top] \
1502 -font $uifont
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001503 grid $top.buts.ok $top.buts.can
1504 grid columnconfigure $top.buts 0 -weight 1 -uniform a
1505 grid columnconfigure $top.buts 1 -weight 1 -uniform a
1506 grid $top.buts - -pady 10 -sticky ew
1507 focus $top.t
1508}
1509
Paul Mackerras908c3582006-05-20 09:38:11 +10001510proc doviewmenu {m first cmd op argv} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001511 set nmenu [$m index end]
1512 for {set i $first} {$i <= $nmenu} {incr i} {
1513 if {[$m entrycget $i -command] eq $cmd} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001514 eval $m $op $i $argv
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001515 break
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001516 }
1517 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001518}
1519
1520proc allviewmenus {n op args} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001521 global viewhlmenu
1522
Paul Mackerras3cd204e2006-11-23 21:06:16 +11001523 doviewmenu .bar.view 5 [list showview $n] $op $args
Paul Mackerras908c3582006-05-20 09:38:11 +10001524 doviewmenu $viewhlmenu 1 [list addvhighlight $n] $op $args
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001525}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001526
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001527proc newviewok {top n} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001528 global nextviewnum newviewperm newviewname newishighlight
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001529 global viewname viewfiles viewperm selectedview curview
Paul Mackerras908c3582006-05-20 09:38:11 +10001530 global viewargs newviewargs viewhlmenu
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001531
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001532 if {[catch {
1533 set newargs [shellsplit $newviewargs($n)]
1534 } err]} {
1535 error_popup "Error in commit selection arguments: $err"
1536 wm raise $top
1537 focus $top
1538 return
1539 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001540 set files {}
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001541 foreach f [split [$top.t get 0.0 end] "\n"] {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001542 set ft [string trim $f]
1543 if {$ft ne {}} {
1544 lappend files $ft
1545 }
1546 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001547 if {![info exists viewfiles($n)]} {
1548 # creating a new view
1549 incr nextviewnum
1550 set viewname($n) $newviewname($n)
1551 set viewperm($n) $newviewperm($n)
1552 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001553 set viewargs($n) $newargs
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001554 addviewmenu $n
1555 if {!$newishighlight} {
1556 after idle showview $n
1557 } else {
Paul Mackerras908c3582006-05-20 09:38:11 +10001558 after idle addvhighlight $n
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001559 }
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001560 } else {
1561 # editing an existing view
1562 set viewperm($n) $newviewperm($n)
1563 if {$newviewname($n) ne $viewname($n)} {
1564 set viewname($n) $newviewname($n)
Paul Mackerras3cd204e2006-11-23 21:06:16 +11001565 doviewmenu .bar.view 5 [list showview $n] \
Paul Mackerras908c3582006-05-20 09:38:11 +10001566 entryconf [list -label $viewname($n)]
1567 doviewmenu $viewhlmenu 1 [list addvhighlight $n] \
1568 entryconf [list -label $viewname($n) -value $viewname($n)]
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001569 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001570 if {$files ne $viewfiles($n) || $newargs ne $viewargs($n)} {
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001571 set viewfiles($n) $files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001572 set viewargs($n) $newargs
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001573 if {$curview == $n} {
1574 after idle updatecommits
1575 }
1576 }
1577 }
1578 catch {destroy $top}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001579}
1580
1581proc delview {} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001582 global curview viewdata viewperm hlview selectedhlview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001583
1584 if {$curview == 0} return
Paul Mackerras908c3582006-05-20 09:38:11 +10001585 if {[info exists hlview] && $hlview == $curview} {
1586 set selectedhlview None
1587 unset hlview
1588 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001589 allviewmenus $curview delete
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001590 set viewdata($curview) {}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001591 set viewperm($curview) 0
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001592 showview 0
1593}
1594
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001595proc addviewmenu {n} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001596 global viewname viewhlmenu
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001597
1598 .bar.view add radiobutton -label $viewname($n) \
1599 -command [list showview $n] -variable selectedview -value $n
Paul Mackerras908c3582006-05-20 09:38:11 +10001600 $viewhlmenu add radiobutton -label $viewname($n) \
1601 -command [list addvhighlight $n] -variable selectedhlview
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001602}
1603
Paul Mackerras22626ef2006-04-17 09:56:02 +10001604proc flatten {var} {
1605 global $var
1606
1607 set ret {}
1608 foreach i [array names $var] {
1609 lappend ret $i [set $var\($i\)]
1610 }
1611 return $ret
1612}
1613
1614proc unflatten {var l} {
1615 global $var
1616
1617 catch {unset $var}
1618 foreach {i v} $l {
1619 set $var\($i\) $v
1620 }
1621}
1622
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001623proc showview {n} {
1624 global curview viewdata viewfiles
1625 global displayorder parentlist childlist rowidlist rowoffsets
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001626 global colormap rowtextx commitrow nextcolor canvxmax
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001627 global numcommits rowrangelist commitlisted idrowranges
1628 global selectedline currentid canv canvy0
1629 global matchinglines treediffs
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10001630 global pending_select phase
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001631 global commitidx rowlaidout rowoptim linesegends
Paul Mackerras22626ef2006-04-17 09:56:02 +10001632 global commfd nextupdate
Paul Mackerras908c3582006-05-20 09:38:11 +10001633 global selectedview
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001634 global vparentlist vchildlist vdisporder vcmitlisted
Paul Mackerras908c3582006-05-20 09:38:11 +10001635 global hlview selectedhlview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001636
1637 if {$n == $curview} return
1638 set selid {}
1639 if {[info exists selectedline]} {
1640 set selid $currentid
1641 set y [yc $selectedline]
1642 set ymax [lindex [$canv cget -scrollregion] 3]
1643 set span [$canv yview]
1644 set ytop [expr {[lindex $span 0] * $ymax}]
1645 set ybot [expr {[lindex $span 1] * $ymax}]
1646 if {$ytop < $y && $y < $ybot} {
1647 set yscreen [expr {$y - $ytop}]
1648 } else {
1649 set yscreen [expr {($ybot - $ytop) / 2}]
1650 }
1651 }
1652 unselectline
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10001653 normalline
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001654 stopfindproc
Paul Mackerras22626ef2006-04-17 09:56:02 +10001655 if {$curview >= 0} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001656 set vparentlist($curview) $parentlist
1657 set vchildlist($curview) $childlist
1658 set vdisporder($curview) $displayorder
1659 set vcmitlisted($curview) $commitlisted
Paul Mackerras22626ef2006-04-17 09:56:02 +10001660 if {$phase ne {}} {
1661 set viewdata($curview) \
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001662 [list $phase $rowidlist $rowoffsets $rowrangelist \
1663 [flatten idrowranges] [flatten idinlist] \
1664 $rowlaidout $rowoptim $numcommits $linesegends]
Paul Mackerras2516dae2006-04-21 10:35:31 +10001665 } elseif {![info exists viewdata($curview)]
1666 || [lindex $viewdata($curview) 0] ne {}} {
Paul Mackerras22626ef2006-04-17 09:56:02 +10001667 set viewdata($curview) \
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001668 [list {} $rowidlist $rowoffsets $rowrangelist]
Paul Mackerras22626ef2006-04-17 09:56:02 +10001669 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001670 }
1671 catch {unset matchinglines}
1672 catch {unset treediffs}
1673 clear_display
Paul Mackerras908c3582006-05-20 09:38:11 +10001674 if {[info exists hlview] && $hlview == $n} {
1675 unset hlview
1676 set selectedhlview None
1677 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001678
1679 set curview $n
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10001680 set selectedview $n
Paul Mackerras3cd204e2006-11-23 21:06:16 +11001681 .bar.view entryconf Edit* -state [expr {$n == 0? "disabled": "normal"}]
1682 .bar.view entryconf Delete* -state [expr {$n == 0? "disabled": "normal"}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001683
1684 if {![info exists viewdata($n)]} {
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10001685 set pending_select $selid
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10001686 getcommits
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001687 return
1688 }
1689
Paul Mackerras22626ef2006-04-17 09:56:02 +10001690 set v $viewdata($n)
1691 set phase [lindex $v 0]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001692 set displayorder $vdisporder($n)
1693 set parentlist $vparentlist($n)
1694 set childlist $vchildlist($n)
1695 set commitlisted $vcmitlisted($n)
1696 set rowidlist [lindex $v 1]
1697 set rowoffsets [lindex $v 2]
1698 set rowrangelist [lindex $v 3]
Paul Mackerras22626ef2006-04-17 09:56:02 +10001699 if {$phase eq {}} {
1700 set numcommits [llength $displayorder]
1701 catch {unset idrowranges}
Paul Mackerras22626ef2006-04-17 09:56:02 +10001702 } else {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001703 unflatten idrowranges [lindex $v 4]
1704 unflatten idinlist [lindex $v 5]
1705 set rowlaidout [lindex $v 6]
1706 set rowoptim [lindex $v 7]
1707 set numcommits [lindex $v 8]
1708 set linesegends [lindex $v 9]
Paul Mackerras22626ef2006-04-17 09:56:02 +10001709 }
1710
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001711 catch {unset colormap}
1712 catch {unset rowtextx}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001713 set nextcolor 0
1714 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001715 set curview $n
1716 set row 0
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001717 setcanvscroll
1718 set yf 0
1719 set row 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001720 if {$selid ne {} && [info exists commitrow($n,$selid)]} {
1721 set row $commitrow($n,$selid)
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001722 # try to get the selected row in the same position on the screen
1723 set ymax [lindex [$canv cget -scrollregion] 3]
1724 set ytop [expr {[yc $row] - $yscreen}]
1725 if {$ytop < 0} {
1726 set ytop 0
1727 }
1728 set yf [expr {$ytop * 1.0 / $ymax}]
1729 }
1730 allcanvs yview moveto $yf
1731 drawvisible
1732 selectline $row 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001733 if {$phase ne {}} {
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001734 if {$phase eq "getcommits"} {
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001735 show_status "Reading commits..."
Paul Mackerrasd16c0812006-04-25 21:21:10 +10001736 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001737 if {[info exists commfd($n)]} {
Paul Mackerrasd1e46752006-08-16 20:02:32 +10001738 layoutmore {}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001739 } else {
1740 finishcommits
1741 }
Paul Mackerras098dd8a2006-05-03 09:32:53 +10001742 } elseif {$numcommits == 0} {
1743 show_status "No commits selected"
Paul Mackerras2516dae2006-04-21 10:35:31 +10001744 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10001745}
1746
Paul Mackerras908c3582006-05-20 09:38:11 +10001747# Stuff relating to the highlighting facility
1748
1749proc ishighlighted {row} {
Paul Mackerras164ff272006-05-29 19:50:02 +10001750 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras908c3582006-05-20 09:38:11 +10001751
1752 if {[info exists nhighlights($row)] && $nhighlights($row) > 0} {
1753 return $nhighlights($row)
1754 }
1755 if {[info exists vhighlights($row)] && $vhighlights($row) > 0} {
1756 return $vhighlights($row)
1757 }
1758 if {[info exists fhighlights($row)] && $fhighlights($row) > 0} {
1759 return $fhighlights($row)
1760 }
Paul Mackerras164ff272006-05-29 19:50:02 +10001761 if {[info exists rhighlights($row)] && $rhighlights($row) > 0} {
1762 return $rhighlights($row)
1763 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001764 return 0
1765}
1766
1767proc bolden {row font} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001768 global canv linehtag selectedline boldrows
Paul Mackerras908c3582006-05-20 09:38:11 +10001769
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001770 lappend boldrows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10001771 $canv itemconf $linehtag($row) -font $font
Paul Mackerras5864c082006-05-26 22:22:48 +10001772 if {[info exists selectedline] && $row == $selectedline} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001773 $canv delete secsel
1774 set t [eval $canv create rect [$canv bbox $linehtag($row)] \
1775 -outline {{}} -tags secsel \
1776 -fill [$canv cget -selectbackground]]
1777 $canv lower $t
1778 }
1779}
1780
1781proc bolden_name {row font} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001782 global canv2 linentag selectedline boldnamerows
Paul Mackerras908c3582006-05-20 09:38:11 +10001783
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001784 lappend boldnamerows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10001785 $canv2 itemconf $linentag($row) -font $font
Paul Mackerras5864c082006-05-26 22:22:48 +10001786 if {[info exists selectedline] && $row == $selectedline} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001787 $canv2 delete secsel
1788 set t [eval $canv2 create rect [$canv2 bbox $linentag($row)] \
1789 -outline {{}} -tags secsel \
1790 -fill [$canv2 cget -selectbackground]]
1791 $canv2 lower $t
1792 }
1793}
1794
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001795proc unbolden {} {
1796 global mainfont boldrows
Paul Mackerras908c3582006-05-20 09:38:11 +10001797
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001798 set stillbold {}
1799 foreach row $boldrows {
Paul Mackerras908c3582006-05-20 09:38:11 +10001800 if {![ishighlighted $row]} {
1801 bolden $row $mainfont
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001802 } else {
1803 lappend stillbold $row
Paul Mackerras908c3582006-05-20 09:38:11 +10001804 }
1805 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001806 set boldrows $stillbold
Paul Mackerras908c3582006-05-20 09:38:11 +10001807}
1808
1809proc addvhighlight {n} {
1810 global hlview curview viewdata vhl_done vhighlights commitidx
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001811
1812 if {[info exists hlview]} {
Paul Mackerras908c3582006-05-20 09:38:11 +10001813 delvhighlight
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001814 }
1815 set hlview $n
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001816 if {$n != $curview && ![info exists viewdata($n)]} {
1817 set viewdata($n) [list getcommits {{}} {{}} {} {} {} 0 0 0 {}]
1818 set vparentlist($n) {}
1819 set vchildlist($n) {}
1820 set vdisporder($n) {}
1821 set vcmitlisted($n) {}
1822 start_rev_list $n
Paul Mackerras908c3582006-05-20 09:38:11 +10001823 }
1824 set vhl_done $commitidx($hlview)
1825 if {$vhl_done > 0} {
1826 drawvisible
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001827 }
1828}
1829
Paul Mackerras908c3582006-05-20 09:38:11 +10001830proc delvhighlight {} {
1831 global hlview vhighlights
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001832
1833 if {![info exists hlview]} return
1834 unset hlview
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001835 catch {unset vhighlights}
1836 unbolden
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001837}
1838
Paul Mackerras908c3582006-05-20 09:38:11 +10001839proc vhighlightmore {} {
1840 global hlview vhl_done commitidx vhighlights
1841 global displayorder vdisporder curview mainfont
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001842
1843 set font [concat $mainfont bold]
1844 set max $commitidx($hlview)
1845 if {$hlview == $curview} {
1846 set disp $displayorder
1847 } else {
1848 set disp $vdisporder($hlview)
1849 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001850 set vr [visiblerows]
1851 set r0 [lindex $vr 0]
1852 set r1 [lindex $vr 1]
1853 for {set i $vhl_done} {$i < $max} {incr i} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001854 set id [lindex $disp $i]
1855 if {[info exists commitrow($curview,$id)]} {
1856 set row $commitrow($curview,$id)
Paul Mackerras908c3582006-05-20 09:38:11 +10001857 if {$r0 <= $row && $row <= $r1} {
1858 if {![highlighted $row]} {
1859 bolden $row $font
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001860 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001861 set vhighlights($row) 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10001862 }
1863 }
1864 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001865 set vhl_done $max
1866}
1867
1868proc askvhighlight {row id} {
1869 global hlview vhighlights commitrow iddrawn mainfont
1870
1871 if {[info exists commitrow($hlview,$id)]} {
1872 if {[info exists iddrawn($id)] && ![ishighlighted $row]} {
1873 bolden $row [concat $mainfont bold]
1874 }
1875 set vhighlights($row) 1
1876 } else {
1877 set vhighlights($row) 0
1878 }
1879}
1880
1881proc hfiles_change {name ix op} {
1882 global highlight_files filehighlight fhighlights fh_serial
Paul Mackerras63b79192006-05-20 21:31:52 +10001883 global mainfont highlight_paths
Paul Mackerras908c3582006-05-20 09:38:11 +10001884
1885 if {[info exists filehighlight]} {
1886 # delete previous highlights
1887 catch {close $filehighlight}
1888 unset filehighlight
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001889 catch {unset fhighlights}
1890 unbolden
Paul Mackerras63b79192006-05-20 21:31:52 +10001891 unhighlight_filelist
Paul Mackerras908c3582006-05-20 09:38:11 +10001892 }
Paul Mackerras63b79192006-05-20 21:31:52 +10001893 set highlight_paths {}
Paul Mackerras908c3582006-05-20 09:38:11 +10001894 after cancel do_file_hl $fh_serial
1895 incr fh_serial
1896 if {$highlight_files ne {}} {
1897 after 300 do_file_hl $fh_serial
1898 }
1899}
1900
Paul Mackerras63b79192006-05-20 21:31:52 +10001901proc makepatterns {l} {
1902 set ret {}
1903 foreach e $l {
1904 set ee [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} $e]
1905 if {[string index $ee end] eq "/"} {
1906 lappend ret "$ee*"
1907 } else {
1908 lappend ret $ee
1909 lappend ret "$ee/*"
1910 }
1911 }
1912 return $ret
1913}
1914
Paul Mackerras908c3582006-05-20 09:38:11 +10001915proc do_file_hl {serial} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001916 global highlight_files filehighlight highlight_paths gdttype fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001917
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001918 if {$gdttype eq "touching paths:"} {
1919 if {[catch {set paths [shellsplit $highlight_files]}]} return
1920 set highlight_paths [makepatterns $paths]
1921 highlight_filelist
1922 set gdtargs [concat -- $paths]
1923 } else {
1924 set gdtargs [list "-S$highlight_files"]
1925 }
Brandon Casey1ce09dd2007-03-19 18:00:37 -05001926 set cmd [concat | git diff-tree -r -s --stdin $gdtargs]
Paul Mackerras908c3582006-05-20 09:38:11 +10001927 set filehighlight [open $cmd r+]
1928 fconfigure $filehighlight -blocking 0
1929 fileevent $filehighlight readable readfhighlight
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001930 set fhl_list {}
Paul Mackerras908c3582006-05-20 09:38:11 +10001931 drawvisible
1932 flushhighlights
1933}
1934
1935proc flushhighlights {} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001936 global filehighlight fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001937
1938 if {[info exists filehighlight]} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001939 lappend fhl_list {}
Paul Mackerras908c3582006-05-20 09:38:11 +10001940 puts $filehighlight ""
1941 flush $filehighlight
1942 }
1943}
1944
1945proc askfilehighlight {row id} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001946 global filehighlight fhighlights fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001947
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001948 lappend fhl_list $id
1949 set fhighlights($row) -1
Paul Mackerras908c3582006-05-20 09:38:11 +10001950 puts $filehighlight $id
1951}
1952
1953proc readfhighlight {} {
1954 global filehighlight fhighlights commitrow curview mainfont iddrawn
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001955 global fhl_list
Paul Mackerras908c3582006-05-20 09:38:11 +10001956
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001957 while {[gets $filehighlight line] >= 0} {
1958 set line [string trim $line]
1959 set i [lsearch -exact $fhl_list $line]
1960 if {$i < 0} continue
1961 for {set j 0} {$j < $i} {incr j} {
1962 set id [lindex $fhl_list $j]
1963 if {[info exists commitrow($curview,$id)]} {
1964 set fhighlights($commitrow($curview,$id)) 0
1965 }
Paul Mackerras908c3582006-05-20 09:38:11 +10001966 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001967 set fhl_list [lrange $fhl_list [expr {$i+1}] end]
1968 if {$line eq {}} continue
1969 if {![info exists commitrow($curview,$line)]} continue
1970 set row $commitrow($curview,$line)
1971 if {[info exists iddrawn($line)] && ![ishighlighted $row]} {
1972 bolden $row [concat $mainfont bold]
1973 }
1974 set fhighlights($row) 1
Paul Mackerras908c3582006-05-20 09:38:11 +10001975 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001976 if {[eof $filehighlight]} {
1977 # strange...
Brandon Casey1ce09dd2007-03-19 18:00:37 -05001978 puts "oops, git diff-tree died"
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001979 catch {close $filehighlight}
1980 unset filehighlight
Paul Mackerras908c3582006-05-20 09:38:11 +10001981 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001982 next_hlcont
Paul Mackerras908c3582006-05-20 09:38:11 +10001983}
1984
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001985proc find_change {name ix op} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001986 global nhighlights mainfont boldnamerows
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001987 global findstring findpattern findtype
Paul Mackerras908c3582006-05-20 09:38:11 +10001988
1989 # delete previous highlights, if any
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001990 foreach row $boldnamerows {
1991 bolden_name $row $mainfont
Paul Mackerras908c3582006-05-20 09:38:11 +10001992 }
Paul Mackerras4e7d6772006-05-30 21:33:07 +10001993 set boldnamerows {}
1994 catch {unset nhighlights}
1995 unbolden
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10001996 if {$findtype ne "Regexp"} {
1997 set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \
1998 $findstring]
1999 set findpattern "*$e*"
Paul Mackerras908c3582006-05-20 09:38:11 +10002000 }
2001 drawvisible
2002}
2003
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10002004proc askfindhighlight {row id} {
2005 global nhighlights commitinfo iddrawn mainfont
2006 global findstring findtype findloc findpattern
Paul Mackerras908c3582006-05-20 09:38:11 +10002007
2008 if {![info exists commitinfo($id)]} {
2009 getcommit $id
2010 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10002011 set info $commitinfo($id)
Paul Mackerras908c3582006-05-20 09:38:11 +10002012 set isbold 0
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10002013 set fldtypes {Headline Author Date Committer CDate Comments}
2014 foreach f $info ty $fldtypes {
2015 if {$findloc ne "All fields" && $findloc ne $ty} {
2016 continue
Paul Mackerras908c3582006-05-20 09:38:11 +10002017 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10002018 if {$findtype eq "Regexp"} {
2019 set doesmatch [regexp $findstring $f]
2020 } elseif {$findtype eq "IgnCase"} {
2021 set doesmatch [string match -nocase $findpattern $f]
2022 } else {
2023 set doesmatch [string match $findpattern $f]
2024 }
2025 if {$doesmatch} {
2026 if {$ty eq "Author"} {
2027 set isbold 2
2028 } else {
2029 set isbold 1
2030 }
Paul Mackerras908c3582006-05-20 09:38:11 +10002031 }
2032 }
2033 if {[info exists iddrawn($id)]} {
2034 if {$isbold && ![ishighlighted $row]} {
2035 bolden $row [concat $mainfont bold]
2036 }
2037 if {$isbold >= 2} {
2038 bolden_name $row [concat $mainfont bold]
2039 }
2040 }
2041 set nhighlights($row) $isbold
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002042}
2043
Paul Mackerras164ff272006-05-29 19:50:02 +10002044proc vrel_change {name ix op} {
2045 global highlight_related
2046
2047 rhighlight_none
2048 if {$highlight_related ne "None"} {
2049 after idle drawvisible
2050 }
2051}
2052
2053# prepare for testing whether commits are descendents or ancestors of a
2054proc rhighlight_sel {a} {
2055 global descendent desc_todo ancestor anc_todo
2056 global highlight_related rhighlights
2057
2058 catch {unset descendent}
2059 set desc_todo [list $a]
2060 catch {unset ancestor}
2061 set anc_todo [list $a]
2062 if {$highlight_related ne "None"} {
2063 rhighlight_none
2064 after idle drawvisible
2065 }
2066}
2067
2068proc rhighlight_none {} {
2069 global rhighlights
2070
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002071 catch {unset rhighlights}
2072 unbolden
Paul Mackerras164ff272006-05-29 19:50:02 +10002073}
2074
2075proc is_descendent {a} {
2076 global curview children commitrow descendent desc_todo
2077
2078 set v $curview
2079 set la $commitrow($v,$a)
2080 set todo $desc_todo
2081 set leftover {}
2082 set done 0
2083 for {set i 0} {$i < [llength $todo]} {incr i} {
2084 set do [lindex $todo $i]
2085 if {$commitrow($v,$do) < $la} {
2086 lappend leftover $do
2087 continue
2088 }
2089 foreach nk $children($v,$do) {
2090 if {![info exists descendent($nk)]} {
2091 set descendent($nk) 1
2092 lappend todo $nk
2093 if {$nk eq $a} {
2094 set done 1
2095 }
2096 }
2097 }
2098 if {$done} {
2099 set desc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
2100 return
2101 }
2102 }
2103 set descendent($a) 0
2104 set desc_todo $leftover
2105}
2106
2107proc is_ancestor {a} {
2108 global curview parentlist commitrow ancestor anc_todo
2109
2110 set v $curview
2111 set la $commitrow($v,$a)
2112 set todo $anc_todo
2113 set leftover {}
2114 set done 0
2115 for {set i 0} {$i < [llength $todo]} {incr i} {
2116 set do [lindex $todo $i]
2117 if {![info exists commitrow($v,$do)] || $commitrow($v,$do) > $la} {
2118 lappend leftover $do
2119 continue
2120 }
2121 foreach np [lindex $parentlist $commitrow($v,$do)] {
2122 if {![info exists ancestor($np)]} {
2123 set ancestor($np) 1
2124 lappend todo $np
2125 if {$np eq $a} {
2126 set done 1
2127 }
2128 }
2129 }
2130 if {$done} {
2131 set anc_todo [concat $leftover [lrange $todo [expr {$i+1}] end]]
2132 return
2133 }
2134 }
2135 set ancestor($a) 0
2136 set anc_todo $leftover
2137}
2138
2139proc askrelhighlight {row id} {
2140 global descendent highlight_related iddrawn mainfont rhighlights
2141 global selectedline ancestor
2142
2143 if {![info exists selectedline]} return
2144 set isbold 0
2145 if {$highlight_related eq "Descendent" ||
2146 $highlight_related eq "Not descendent"} {
2147 if {![info exists descendent($id)]} {
2148 is_descendent $id
2149 }
2150 if {$descendent($id) == ($highlight_related eq "Descendent")} {
2151 set isbold 1
2152 }
2153 } elseif {$highlight_related eq "Ancestor" ||
2154 $highlight_related eq "Not ancestor"} {
2155 if {![info exists ancestor($id)]} {
2156 is_ancestor $id
2157 }
2158 if {$ancestor($id) == ($highlight_related eq "Ancestor")} {
2159 set isbold 1
2160 }
2161 }
2162 if {[info exists iddrawn($id)]} {
2163 if {$isbold && ![ishighlighted $row]} {
2164 bolden $row [concat $mainfont bold]
2165 }
2166 }
2167 set rhighlights($row) $isbold
2168}
2169
Paul Mackerras4e7d6772006-05-30 21:33:07 +10002170proc next_hlcont {} {
2171 global fhl_row fhl_dirn displayorder numcommits
2172 global vhighlights fhighlights nhighlights rhighlights
2173 global hlview filehighlight findstring highlight_related
2174
2175 if {![info exists fhl_dirn] || $fhl_dirn == 0} return
2176 set row $fhl_row
2177 while {1} {
2178 if {$row < 0 || $row >= $numcommits} {
2179 bell
2180 set fhl_dirn 0
2181 return
2182 }
2183 set id [lindex $displayorder $row]
2184 if {[info exists hlview]} {
2185 if {![info exists vhighlights($row)]} {
2186 askvhighlight $row $id
2187 }
2188 if {$vhighlights($row) > 0} break
2189 }
2190 if {$findstring ne {}} {
2191 if {![info exists nhighlights($row)]} {
2192 askfindhighlight $row $id
2193 }
2194 if {$nhighlights($row) > 0} break
2195 }
2196 if {$highlight_related ne "None"} {
2197 if {![info exists rhighlights($row)]} {
2198 askrelhighlight $row $id
2199 }
2200 if {$rhighlights($row) > 0} break
2201 }
2202 if {[info exists filehighlight]} {
2203 if {![info exists fhighlights($row)]} {
2204 # ask for a few more while we're at it...
2205 set r $row
2206 for {set n 0} {$n < 100} {incr n} {
2207 if {![info exists fhighlights($r)]} {
2208 askfilehighlight $r [lindex $displayorder $r]
2209 }
2210 incr r $fhl_dirn
2211 if {$r < 0 || $r >= $numcommits} break
2212 }
2213 flushhighlights
2214 }
2215 if {$fhighlights($row) < 0} {
2216 set fhl_row $row
2217 return
2218 }
2219 if {$fhighlights($row) > 0} break
2220 }
2221 incr row $fhl_dirn
2222 }
2223 set fhl_dirn 0
2224 selectline $row 1
2225}
2226
2227proc next_highlight {dirn} {
2228 global selectedline fhl_row fhl_dirn
2229 global hlview filehighlight findstring highlight_related
2230
2231 if {![info exists selectedline]} return
2232 if {!([info exists hlview] || $findstring ne {} ||
2233 $highlight_related ne "None" || [info exists filehighlight])} return
2234 set fhl_row [expr {$selectedline + $dirn}]
2235 set fhl_dirn $dirn
2236 next_hlcont
2237}
2238
2239proc cancel_next_highlight {} {
2240 global fhl_dirn
2241
2242 set fhl_dirn 0
2243}
2244
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002245# Graph layout functions
2246
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002247proc shortids {ids} {
2248 set res {}
2249 foreach id $ids {
2250 if {[llength $id] > 1} {
2251 lappend res [shortids $id]
2252 } elseif {[regexp {^[0-9a-f]{40}$} $id]} {
2253 lappend res [string range $id 0 7]
2254 } else {
2255 lappend res $id
2256 }
2257 }
2258 return $res
2259}
2260
2261proc incrange {l x o} {
2262 set n [llength $l]
2263 while {$x < $n} {
2264 set e [lindex $l $x]
2265 if {$e ne {}} {
2266 lset l $x [expr {$e + $o}]
2267 }
2268 incr x
2269 }
2270 return $l
2271}
2272
2273proc ntimes {n o} {
2274 set ret {}
2275 for {} {$n > 0} {incr n -1} {
2276 lappend ret $o
2277 }
2278 return $ret
2279}
2280
2281proc usedinrange {id l1 l2} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002282 global children commitrow childlist curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002283
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002284 if {[info exists commitrow($curview,$id)]} {
2285 set r $commitrow($curview,$id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002286 if {$l1 <= $r && $r <= $l2} {
2287 return [expr {$r - $l1 + 1}]
2288 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002289 set kids [lindex $childlist $r]
2290 } else {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002291 set kids $children($curview,$id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002292 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002293 foreach c $kids {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002294 set r $commitrow($curview,$c)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002295 if {$l1 <= $r && $r <= $l2} {
2296 return [expr {$r - $l1 + 1}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002297 }
2298 }
2299 return 0
2300}
2301
2302proc sanity {row {full 0}} {
2303 global rowidlist rowoffsets
2304
2305 set col -1
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002306 set ids [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002307 foreach id $ids {
2308 incr col
2309 if {$id eq {}} continue
2310 if {$col < [llength $ids] - 1 &&
2311 [lsearch -exact -start [expr {$col+1}] $ids $id] >= 0} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002312 puts "oops: [shortids $id] repeated in row $row col $col: {[shortids [lindex $rowidlist $row]]}"
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002313 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002314 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002315 set y $row
2316 set x $col
2317 while {$o ne {}} {
2318 incr y -1
2319 incr x $o
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002320 if {[lindex $rowidlist $y $x] != $id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002321 puts "oops: rowoffsets wrong at row [expr {$y+1}] col [expr {$x-$o}]"
2322 puts " id=[shortids $id] check started at row $row"
2323 for {set i $row} {$i >= $y} {incr i -1} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002324 puts " row $i ids={[shortids [lindex $rowidlist $i]]} offs={[lindex $rowoffsets $i]}"
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002325 }
2326 break
2327 }
2328 if {!$full} break
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002329 set o [lindex $rowoffsets $y $x]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002330 }
2331 }
2332}
2333
2334proc makeuparrow {oid x y z} {
2335 global rowidlist rowoffsets uparrowlen idrowranges
2336
2337 for {set i 1} {$i < $uparrowlen && $y > 1} {incr i} {
2338 incr y -1
2339 incr x $z
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002340 set off0 [lindex $rowoffsets $y]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002341 for {set x0 $x} {1} {incr x0} {
2342 if {$x0 >= [llength $off0]} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002343 set x0 [llength [lindex $rowoffsets [expr {$y-1}]]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002344 break
2345 }
2346 set z [lindex $off0 $x0]
2347 if {$z ne {}} {
2348 incr x0 $z
2349 break
2350 }
2351 }
2352 set z [expr {$x0 - $x}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002353 lset rowidlist $y [linsert [lindex $rowidlist $y] $x $oid]
2354 lset rowoffsets $y [linsert [lindex $rowoffsets $y] $x $z]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002355 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002356 set tmp [lreplace [lindex $rowoffsets $y] $x $x {}]
2357 lset rowoffsets $y [incrange $tmp [expr {$x+1}] -1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002358 lappend idrowranges($oid) $y
2359}
2360
2361proc initlayout {} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10002362 global rowidlist rowoffsets displayorder commitlisted
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002363 global rowlaidout rowoptim
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002364 global idinlist rowchk rowrangelist idrowranges
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002365 global numcommits canvxmax canv
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002366 global nextcolor
Paul Mackerras79b2c752006-04-02 20:47:40 +10002367 global parentlist childlist children
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002368 global colormap rowtextx
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002369 global linesegends
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002370
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002371 set numcommits 0
2372 set displayorder {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002373 set commitlisted {}
2374 set parentlist {}
2375 set childlist {}
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002376 set rowrangelist {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002377 set nextcolor 0
2378 set rowidlist {{}}
2379 set rowoffsets {{}}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002380 catch {unset idinlist}
2381 catch {unset rowchk}
2382 set rowlaidout 0
2383 set rowoptim 0
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11002384 set canvxmax [$canv cget -width]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002385 catch {unset colormap}
2386 catch {unset rowtextx}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002387 catch {unset idrowranges}
Paul Mackerras22626ef2006-04-17 09:56:02 +10002388 set linesegends {}
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11002389}
2390
2391proc setcanvscroll {} {
2392 global canv canv2 canv3 numcommits linespc canvxmax canvy0
2393
2394 set ymax [expr {$canvy0 + ($numcommits - 0.5) * $linespc + 2}]
2395 $canv conf -scrollregion [list 0 0 $canvxmax $ymax]
2396 $canv2 conf -scrollregion [list 0 0 0 $ymax]
2397 $canv3 conf -scrollregion [list 0 0 0 $ymax]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002398}
2399
2400proc visiblerows {} {
2401 global canv numcommits linespc
2402
2403 set ymax [lindex [$canv cget -scrollregion] 3]
2404 if {$ymax eq {} || $ymax == 0} return
2405 set f [$canv yview]
2406 set y0 [expr {int([lindex $f 0] * $ymax)}]
2407 set r0 [expr {int(($y0 - 3) / $linespc) - 1}]
2408 if {$r0 < 0} {
2409 set r0 0
2410 }
2411 set y1 [expr {int([lindex $f 1] * $ymax)}]
2412 set r1 [expr {int(($y1 - 3) / $linespc) + 1}]
2413 if {$r1 >= $numcommits} {
2414 set r1 [expr {$numcommits - 1}]
2415 }
2416 return [list $r0 $r1]
2417}
2418
Paul Mackerrasd1e46752006-08-16 20:02:32 +10002419proc layoutmore {tmax} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002420 global rowlaidout rowoptim commitidx numcommits optim_delay
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002421 global uparrowlen curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002422
Paul Mackerrasd1e46752006-08-16 20:02:32 +10002423 while {1} {
2424 if {$rowoptim - $optim_delay > $numcommits} {
2425 showstuff [expr {$rowoptim - $optim_delay}]
2426 } elseif {$rowlaidout - $uparrowlen - 1 > $rowoptim} {
2427 set nr [expr {$rowlaidout - $uparrowlen - 1 - $rowoptim}]
2428 if {$nr > 100} {
2429 set nr 100
2430 }
2431 optimize_rows $rowoptim 0 [expr {$rowoptim + $nr}]
2432 incr rowoptim $nr
2433 } elseif {$commitidx($curview) > $rowlaidout} {
2434 set nr [expr {$commitidx($curview) - $rowlaidout}]
2435 # may need to increase this threshold if uparrowlen or
2436 # mingaplen are increased...
2437 if {$nr > 150} {
2438 set nr 150
2439 }
2440 set row $rowlaidout
2441 set rowlaidout [layoutrows $row [expr {$row + $nr}] 0]
2442 if {$rowlaidout == $row} {
2443 return 0
2444 }
2445 } else {
2446 return 0
2447 }
2448 if {$tmax ne {} && [clock clicks -milliseconds] >= $tmax} {
2449 return 1
2450 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002451 }
2452}
2453
2454proc showstuff {canshow} {
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10002455 global numcommits commitrow pending_select selectedline
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002456 global linesegends idrowranges idrangedrawn curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002457
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002458 if {$numcommits == 0} {
2459 global phase
2460 set phase "incrdraw"
2461 allcanvs delete all
2462 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002463 set row $numcommits
2464 set numcommits $canshow
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11002465 setcanvscroll
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002466 set rows [visiblerows]
2467 set r0 [lindex $rows 0]
2468 set r1 [lindex $rows 1]
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002469 set selrow -1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002470 for {set r $row} {$r < $canshow} {incr r} {
Paul Mackerras22626ef2006-04-17 09:56:02 +10002471 foreach id [lindex $linesegends [expr {$r+1}]] {
2472 set i -1
2473 foreach {s e} [rowranges $id] {
2474 incr i
2475 if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0
2476 && ![info exists idrangedrawn($id,$i)]} {
2477 drawlineseg $id $i
2478 set idrangedrawn($id,$i) 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002479 }
2480 }
2481 }
2482 }
2483 if {$canshow > $r1} {
2484 set canshow $r1
2485 }
2486 while {$row < $canshow} {
2487 drawcmitrow $row
2488 incr row
2489 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002490 if {[info exists pending_select] &&
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002491 [info exists commitrow($curview,$pending_select)] &&
2492 $commitrow($curview,$pending_select) < $numcommits} {
2493 selectline $commitrow($curview,$pending_select) 1
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002494 }
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10002495 if {![info exists selectedline] && ![info exists pending_select]} {
2496 selectline 0 1
2497 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002498}
2499
2500proc layoutrows {row endrow last} {
2501 global rowidlist rowoffsets displayorder
2502 global uparrowlen downarrowlen maxwidth mingaplen
Paul Mackerras79b2c752006-04-02 20:47:40 +10002503 global childlist parentlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002504 global idrowranges linesegends
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002505 global commitidx curview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002506 global idinlist rowchk rowrangelist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002507
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002508 set idlist [lindex $rowidlist $row]
2509 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002510 while {$row < $endrow} {
2511 set id [lindex $displayorder $row]
2512 set oldolds {}
2513 set newolds {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002514 foreach p [lindex $parentlist $row] {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002515 if {![info exists idinlist($p)]} {
2516 lappend newolds $p
2517 } elseif {!$idinlist($p)} {
2518 lappend oldolds $p
2519 }
2520 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002521 set lse {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002522 set nev [expr {[llength $idlist] + [llength $newolds]
2523 + [llength $oldolds] - $maxwidth + 1}]
2524 if {$nev > 0} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002525 if {!$last &&
2526 $row + $uparrowlen + $mingaplen >= $commitidx($curview)} break
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002527 for {set x [llength $idlist]} {[incr x -1] >= 0} {} {
2528 set i [lindex $idlist $x]
2529 if {![info exists rowchk($i)] || $row >= $rowchk($i)} {
2530 set r [usedinrange $i [expr {$row - $downarrowlen}] \
2531 [expr {$row + $uparrowlen + $mingaplen}]]
2532 if {$r == 0} {
2533 set idlist [lreplace $idlist $x $x]
2534 set offs [lreplace $offs $x $x]
2535 set offs [incrange $offs $x 1]
2536 set idinlist($i) 0
Paul Mackerrasd8d2df02006-03-18 20:42:46 +11002537 set rm1 [expr {$row - 1}]
Paul Mackerras22626ef2006-04-17 09:56:02 +10002538 lappend lse $i
Paul Mackerrasd8d2df02006-03-18 20:42:46 +11002539 lappend idrowranges($i) $rm1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002540 if {[incr nev -1] <= 0} break
2541 continue
2542 }
2543 set rowchk($id) [expr {$row + $r}]
2544 }
2545 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002546 lset rowidlist $row $idlist
2547 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002548 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10002549 lappend linesegends $lse
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002550 set col [lsearch -exact $idlist $id]
2551 if {$col < 0} {
2552 set col [llength $idlist]
2553 lappend idlist $id
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002554 lset rowidlist $row $idlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002555 set z {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002556 if {[lindex $childlist $row] ne {}} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002557 set z [expr {[llength [lindex $rowidlist [expr {$row-1}]]] - $col}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002558 unset idinlist($id)
2559 }
2560 lappend offs $z
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002561 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002562 if {$z ne {}} {
2563 makeuparrow $id $col $row $z
2564 }
2565 } else {
2566 unset idinlist($id)
2567 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002568 set ranges {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002569 if {[info exists idrowranges($id)]} {
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002570 set ranges $idrowranges($id)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002571 lappend ranges $row
2572 unset idrowranges($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002573 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10002574 lappend rowrangelist $ranges
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002575 incr row
2576 set offs [ntimes [llength $idlist] 0]
2577 set l [llength $newolds]
2578 set idlist [eval lreplace \$idlist $col $col $newolds]
2579 set o 0
2580 if {$l != 1} {
2581 set offs [lrange $offs 0 [expr {$col - 1}]]
2582 foreach x $newolds {
2583 lappend offs {}
2584 incr o -1
2585 }
2586 incr o
2587 set tmp [expr {[llength $idlist] - [llength $offs]}]
2588 if {$tmp > 0} {
2589 set offs [concat $offs [ntimes $tmp $o]]
2590 }
2591 } else {
2592 lset offs $col {}
2593 }
2594 foreach i $newolds {
2595 set idinlist($i) 1
2596 set idrowranges($i) $row
2597 }
2598 incr col $l
2599 foreach oid $oldolds {
2600 set idinlist($oid) 1
2601 set idlist [linsert $idlist $col $oid]
2602 set offs [linsert $offs $col $o]
2603 makeuparrow $oid $col $row $o
2604 incr col
2605 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002606 lappend rowidlist $idlist
2607 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002608 }
2609 return $row
2610}
2611
2612proc addextraid {id row} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10002613 global displayorder commitrow commitinfo
Paul Mackerrase7da3472006-04-17 10:27:59 +10002614 global commitidx commitlisted
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002615 global parentlist childlist children curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002616
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002617 incr commitidx($curview)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002618 lappend displayorder $id
Paul Mackerrase7da3472006-04-17 10:27:59 +10002619 lappend commitlisted 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10002620 lappend parentlist {}
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002621 set commitrow($curview,$id) $row
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002622 readcommit $id
2623 if {![info exists commitinfo($id)]} {
2624 set commitinfo($id) {"No commit information available"}
Paul Mackerras79b2c752006-04-02 20:47:40 +10002625 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002626 if {![info exists children($curview,$id)]} {
2627 set children($curview,$id) {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002628 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002629 lappend childlist $children($curview,$id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002630}
2631
2632proc layouttail {} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002633 global rowidlist rowoffsets idinlist commitidx curview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002634 global idrowranges rowrangelist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002635
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002636 set row $commitidx($curview)
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002637 set idlist [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002638 while {$idlist ne {}} {
2639 set col [expr {[llength $idlist] - 1}]
2640 set id [lindex $idlist $col]
2641 addextraid $id $row
2642 unset idinlist($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002643 lappend idrowranges($id) $row
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002644 lappend rowrangelist $idrowranges($id)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002645 unset idrowranges($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002646 incr row
2647 set offs [ntimes $col 0]
2648 set idlist [lreplace $idlist $col $col]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002649 lappend rowidlist $idlist
2650 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002651 }
2652
2653 foreach id [array names idinlist] {
2654 addextraid $id $row
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002655 lset rowidlist $row [list $id]
2656 lset rowoffsets $row 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002657 makeuparrow $id 0 $row 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002658 lappend idrowranges($id) $row
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002659 lappend rowrangelist $idrowranges($id)
Paul Mackerras22626ef2006-04-17 09:56:02 +10002660 unset idrowranges($id)
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002661 incr row
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002662 lappend rowidlist {}
2663 lappend rowoffsets {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002664 }
2665}
2666
2667proc insert_pad {row col npad} {
2668 global rowidlist rowoffsets
2669
2670 set pad [ntimes $npad {}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002671 lset rowidlist $row [eval linsert [list [lindex $rowidlist $row]] $col $pad]
2672 set tmp [eval linsert [list [lindex $rowoffsets $row]] $col $pad]
2673 lset rowoffsets $row [incrange $tmp [expr {$col + $npad}] [expr {-$npad}]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002674}
2675
2676proc optimize_rows {row col endrow} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002677 global rowidlist rowoffsets idrowranges displayorder
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002678
2679 for {} {$row < $endrow} {incr row} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002680 set idlist [lindex $rowidlist $row]
2681 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002682 set haspad 0
2683 for {} {$col < [llength $offs]} {incr col} {
2684 if {[lindex $idlist $col] eq {}} {
2685 set haspad 1
2686 continue
2687 }
2688 set z [lindex $offs $col]
2689 if {$z eq {}} continue
2690 set isarrow 0
2691 set x0 [expr {$col + $z}]
2692 set y0 [expr {$row - 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002693 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002694 if {$z0 eq {}} {
2695 set id [lindex $idlist $col]
Paul Mackerras22626ef2006-04-17 09:56:02 +10002696 set ranges [rowranges $id]
2697 if {$ranges ne {} && $y0 > [lindex $ranges 0]} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002698 set isarrow 1
2699 }
2700 }
2701 if {$z < -1 || ($z < 0 && $isarrow)} {
2702 set npad [expr {-1 - $z + $isarrow}]
2703 set offs [incrange $offs $col $npad]
2704 insert_pad $y0 $x0 $npad
2705 if {$y0 > 0} {
2706 optimize_rows $y0 $x0 $row
2707 }
2708 set z [lindex $offs $col]
2709 set x0 [expr {$col + $z}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002710 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002711 } elseif {$z > 1 || ($z > 0 && $isarrow)} {
2712 set npad [expr {$z - 1 + $isarrow}]
2713 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002714 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002715 set x1 -1
2716 foreach z $offs2 {
2717 incr x1
2718 if {$z eq {} || $x1 + $z < $col} continue
2719 if {$x1 + $z > $col} {
2720 incr npad
2721 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002722 lset rowoffsets $y1 [incrange $offs2 $x1 $npad]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002723 break
2724 }
2725 set pad [ntimes $npad {}]
2726 set idlist [eval linsert \$idlist $col $pad]
2727 set tmp [eval linsert \$offs $col $pad]
2728 incr col $npad
2729 set offs [incrange $tmp $col [expr {-$npad}]]
2730 set z [lindex $offs $col]
2731 set haspad 1
2732 }
Paul Mackerraseb447a12006-03-18 23:11:37 +11002733 if {$z0 eq {} && !$isarrow} {
2734 # this line links to its first child on row $row-2
2735 set rm2 [expr {$row - 2}]
2736 set id [lindex $displayorder $rm2]
2737 set xc [lsearch -exact [lindex $rowidlist $rm2] $id]
2738 if {$xc >= 0} {
2739 set z0 [expr {$xc - $x0}]
2740 }
2741 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002742 if {$z0 ne {} && $z < 0 && $z0 > 0} {
2743 insert_pad $y0 $x0 1
2744 set offs [incrange $offs $col 1]
2745 optimize_rows $y0 [expr {$x0 + 1}] $row
2746 }
2747 }
2748 if {!$haspad} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11002749 set o {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002750 for {set col [llength $idlist]} {[incr col -1] >= 0} {} {
2751 set o [lindex $offs $col]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002752 if {$o eq {}} {
2753 # check if this is the link to the first child
2754 set id [lindex $idlist $col]
Paul Mackerras22626ef2006-04-17 09:56:02 +10002755 set ranges [rowranges $id]
2756 if {$ranges ne {} && $row == [lindex $ranges 0]} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11002757 # it is, work out offset to child
2758 set y0 [expr {$row - 1}]
2759 set id [lindex $displayorder $y0]
2760 set x0 [lsearch -exact [lindex $rowidlist $y0] $id]
2761 if {$x0 >= 0} {
2762 set o [expr {$x0 - $col}]
2763 }
2764 }
2765 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002766 if {$o eq {} || $o <= 0} break
2767 }
Paul Mackerraseb447a12006-03-18 23:11:37 +11002768 if {$o ne {} && [incr col] < [llength $idlist]} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002769 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002770 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002771 set x1 -1
2772 foreach z $offs2 {
2773 incr x1
2774 if {$z eq {} || $x1 + $z < $col} continue
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002775 lset rowoffsets $y1 [incrange $offs2 $x1 1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002776 break
2777 }
2778 set idlist [linsert $idlist $col {}]
2779 set tmp [linsert $offs $col {}]
2780 incr col
2781 set offs [incrange $tmp $col -1]
2782 }
2783 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002784 lset rowidlist $row $idlist
2785 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002786 set col 0
2787 }
2788}
2789
2790proc xc {row col} {
2791 global canvx0 linespc
2792 return [expr {$canvx0 + $col * $linespc}]
2793}
2794
2795proc yc {row} {
2796 global canvy0 linespc
2797 return [expr {$canvy0 + $row * $linespc}]
2798}
2799
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002800proc linewidth {id} {
2801 global thickerline lthickness
2802
2803 set wid $lthickness
2804 if {[info exists thickerline] && $id eq $thickerline} {
2805 set wid [expr {2 * $lthickness}]
2806 }
2807 return $wid
2808}
2809
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002810proc rowranges {id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002811 global phase idrowranges commitrow rowlaidout rowrangelist curview
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002812
2813 set ranges {}
Paul Mackerras22626ef2006-04-17 09:56:02 +10002814 if {$phase eq {} ||
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002815 ([info exists commitrow($curview,$id)]
2816 && $commitrow($curview,$id) < $rowlaidout)} {
2817 set ranges [lindex $rowrangelist $commitrow($curview,$id)]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002818 } elseif {[info exists idrowranges($id)]} {
2819 set ranges $idrowranges($id)
2820 }
2821 return $ranges
2822}
2823
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002824proc drawlineseg {id i} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002825 global rowoffsets rowidlist
Paul Mackerraseb447a12006-03-18 23:11:37 +11002826 global displayorder
Paul Mackerras879e8b12006-03-31 10:45:14 +11002827 global canv colormap linespc
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002828 global numcommits commitrow curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002829
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002830 set ranges [rowranges $id]
2831 set downarrow 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002832 if {[info exists commitrow($curview,$id)]
2833 && $commitrow($curview,$id) < $numcommits} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002834 set downarrow [expr {$i < [llength $ranges] / 2 - 1}]
2835 } else {
2836 set downarrow 1
2837 }
2838 set startrow [lindex $ranges [expr {2 * $i}]]
2839 set row [lindex $ranges [expr {2 * $i + 1}]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002840 if {$startrow == $row} return
2841 assigncolor $id
2842 set coords {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002843 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002844 if {$col < 0} {
2845 puts "oops: drawline: id $id not on row $row"
2846 return
2847 }
2848 set lasto {}
2849 set ns 0
2850 while {1} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002851 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002852 if {$o eq {}} break
2853 if {$o ne $lasto} {
2854 # changing direction
2855 set x [xc $row $col]
2856 set y [yc $row]
2857 lappend coords $x $y
2858 set lasto $o
2859 }
2860 incr col $o
2861 incr row -1
2862 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002863 set x [xc $row $col]
2864 set y [yc $row]
2865 lappend coords $x $y
Paul Mackerraseb447a12006-03-18 23:11:37 +11002866 if {$i == 0} {
2867 # draw the link to the first child as part of this line
2868 incr row -1
2869 set child [lindex $displayorder $row]
2870 set ccol [lsearch -exact [lindex $rowidlist $row] $child]
2871 if {$ccol >= 0} {
2872 set x [xc $row $ccol]
2873 set y [yc $row]
2874 if {$ccol < $col - 1} {
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11002875 lappend coords [xc $row [expr {$col - 1}]] [yc $row]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002876 } elseif {$ccol > $col + 1} {
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11002877 lappend coords [xc $row [expr {$col + 1}]] [yc $row]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002878 }
2879 lappend coords $x $y
2880 }
2881 }
2882 if {[llength $coords] < 4} return
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002883 if {$downarrow} {
Paul Mackerras879e8b12006-03-31 10:45:14 +11002884 # This line has an arrow at the lower end: check if the arrow is
2885 # on a diagonal segment, and if so, work around the Tk 8.4
2886 # refusal to draw arrows on diagonal lines.
2887 set x0 [lindex $coords 0]
2888 set x1 [lindex $coords 2]
2889 if {$x0 != $x1} {
2890 set y0 [lindex $coords 1]
2891 set y1 [lindex $coords 3]
2892 if {$y0 - $y1 <= 2 * $linespc && $x1 == [lindex $coords 4]} {
2893 # we have a nearby vertical segment, just trim off the diag bit
2894 set coords [lrange $coords 2 end]
2895 } else {
2896 set slope [expr {($x0 - $x1) / ($y0 - $y1)}]
2897 set xi [expr {$x0 - $slope * $linespc / 2}]
2898 set yi [expr {$y0 - $linespc / 2}]
2899 set coords [lreplace $coords 0 1 $xi $y0 $xi $yi]
2900 }
2901 }
2902 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002903 set arrow [expr {2 * ($i > 0) + $downarrow}]
Paul Mackerraseb447a12006-03-18 23:11:37 +11002904 set arrow [lindex {none first last both} $arrow]
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002905 set t [$canv create line $coords -width [linewidth $id] \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002906 -fill $colormap($id) -tags lines.$id -arrow $arrow]
2907 $canv lower $t
2908 bindline $t $id
2909}
2910
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002911proc drawparentlinks {id row col olds} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002912 global rowidlist canv colormap
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002913
2914 set row2 [expr {$row + 1}]
2915 set x [xc $row $col]
2916 set y [yc $row]
2917 set y2 [yc $row2]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002918 set ids [lindex $rowidlist $row2]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002919 # rmx = right-most X coord used
2920 set rmx 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002921 foreach p $olds {
Paul Mackerrasf3408442006-03-31 09:54:24 +11002922 set i [lsearch -exact $ids $p]
2923 if {$i < 0} {
2924 puts "oops, parent $p of $id not in list"
2925 continue
2926 }
2927 set x2 [xc $row2 $i]
2928 if {$x2 > $rmx} {
2929 set rmx $x2
2930 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002931 set ranges [rowranges $p]
2932 if {$ranges ne {} && $row2 == [lindex $ranges 0]
2933 && $row2 < [lindex $ranges 1]} {
Paul Mackerraseb447a12006-03-18 23:11:37 +11002934 # drawlineseg will do this one for us
2935 continue
2936 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002937 assigncolor $p
2938 # should handle duplicated parents here...
2939 set coords [list $x $y]
2940 if {$i < $col - 1} {
2941 lappend coords [xc $row [expr {$i + 1}]] $y
2942 } elseif {$i > $col + 1} {
2943 lappend coords [xc $row [expr {$i - 1}]] $y
2944 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002945 lappend coords $x2 $y2
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002946 set t [$canv create line $coords -width [linewidth $p] \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002947 -fill $colormap($p) -tags lines.$p]
2948 $canv lower $t
2949 bindline $t $p
2950 }
2951 return $rmx
2952}
2953
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002954proc drawlines {id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002955 global colormap canv
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002956 global idrangedrawn
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002957 global children iddrawn commitrow rowidlist curview
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002958
2959 $canv delete lines.$id
Paul Mackerras50b44ec2006-04-04 10:16:22 +10002960 set nr [expr {[llength [rowranges $id]] / 2}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002961 for {set i 0} {$i < $nr} {incr i} {
2962 if {[info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002963 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002964 }
2965 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002966 foreach child $children($curview,$id) {
Paul Mackerras79b2c752006-04-02 20:47:40 +10002967 if {[info exists iddrawn($child)]} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10002968 set row $commitrow($curview,$child)
Paul Mackerras79b2c752006-04-02 20:47:40 +10002969 set col [lsearch -exact [lindex $rowidlist $row] $child]
2970 if {$col >= 0} {
2971 drawparentlinks $child $row $col [list $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002972 }
2973 }
2974 }
2975}
2976
2977proc drawcmittext {id row col rmx} {
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002978 global linespc canv canv2 canv3 canvy0 fgcolor
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002979 global commitlisted commitinfo rowidlist
2980 global rowtextx idpos idtags idheads idotherrefs
2981 global linehtag linentag linedtag
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002982 global mainfont canvxmax boldrows boldnamerows fgcolor
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002983
Paul Mackerras79b2c752006-04-02 20:47:40 +10002984 set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002985 set x [xc $row $col]
2986 set y [yc $row]
2987 set orad [expr {$linespc / 3}]
2988 set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
2989 [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10002990 -fill $ofill -outline $fgcolor -width 1 -tags circle]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002991 $canv raise $t
2992 $canv bind $t <1> {selcanvline {} %x %y}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002993 set xt [xc $row [llength [lindex $rowidlist $row]]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002994 if {$xt < $rmx} {
2995 set xt $rmx
2996 }
2997 set rowtextx($row) $xt
2998 set idpos($id) [list $x $xt $y]
2999 if {[info exists idtags($id)] || [info exists idheads($id)]
3000 || [info exists idotherrefs($id)]} {
3001 set xt [drawtags $id $x $xt $y]
3002 }
3003 set headline [lindex $commitinfo($id) 0]
3004 set name [lindex $commitinfo($id) 1]
3005 set date [lindex $commitinfo($id) 2]
3006 set date [formatdate $date]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003007 set font $mainfont
Paul Mackerras908c3582006-05-20 09:38:11 +10003008 set nfont $mainfont
3009 set isbold [ishighlighted $row]
3010 if {$isbold > 0} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003011 lappend boldrows $row
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003012 lappend font bold
Paul Mackerras908c3582006-05-20 09:38:11 +10003013 if {$isbold > 1} {
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003014 lappend boldnamerows $row
Paul Mackerras908c3582006-05-20 09:38:11 +10003015 lappend nfont bold
3016 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003017 }
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003018 set linehtag($row) [$canv create text $xt $y -anchor w -fill $fgcolor \
3019 -text $headline -font $font -tags text]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003020 $canv bind $linehtag($row) <Button-3> "rowmenu %X %Y $id"
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003021 set linentag($row) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
3022 -text $name -font $nfont -tags text]
3023 set linedtag($row) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
3024 -text $date -font $mainfont -tags text]
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11003025 set xr [expr {$xt + [font measure $mainfont $headline]}]
3026 if {$xr > $canvxmax} {
3027 set canvxmax $xr
3028 setcanvscroll
3029 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003030}
3031
3032proc drawcmitrow {row} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003033 global displayorder rowidlist
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003034 global idrangedrawn iddrawn
Paul Mackerrase7da3472006-04-17 10:27:59 +10003035 global commitinfo parentlist numcommits
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003036 global filehighlight fhighlights findstring nhighlights
Paul Mackerras908c3582006-05-20 09:38:11 +10003037 global hlview vhighlights
Paul Mackerras164ff272006-05-29 19:50:02 +10003038 global highlight_related rhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003039
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003040 if {$row >= $numcommits} return
3041 foreach id [lindex $rowidlist $row] {
Paul Mackerras22626ef2006-04-17 09:56:02 +10003042 if {$id eq {}} continue
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003043 set i -1
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003044 foreach {s e} [rowranges $id] {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003045 incr i
3046 if {$row < $s} continue
3047 if {$e eq {}} break
3048 if {$row <= $e} {
3049 if {$e < $numcommits && ![info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11003050 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003051 set idrangedrawn($id,$i) 1
3052 }
3053 break
3054 }
3055 }
3056 }
3057
3058 set id [lindex $displayorder $row]
Paul Mackerras908c3582006-05-20 09:38:11 +10003059 if {[info exists hlview] && ![info exists vhighlights($row)]} {
3060 askvhighlight $row $id
3061 }
3062 if {[info exists filehighlight] && ![info exists fhighlights($row)]} {
3063 askfilehighlight $row $id
3064 }
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003065 if {$findstring ne {} && ![info exists nhighlights($row)]} {
3066 askfindhighlight $row $id
Paul Mackerras908c3582006-05-20 09:38:11 +10003067 }
Paul Mackerras164ff272006-05-29 19:50:02 +10003068 if {$highlight_related ne "None" && ![info exists rhighlights($row)]} {
3069 askrelhighlight $row $id
3070 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003071 if {[info exists iddrawn($id)]} return
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003072 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003073 if {$col < 0} {
3074 puts "oops, row $row id $id not in list"
3075 return
3076 }
3077 if {![info exists commitinfo($id)]} {
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11003078 getcommit $id
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003079 }
3080 assigncolor $id
Paul Mackerras79b2c752006-04-02 20:47:40 +10003081 set olds [lindex $parentlist $row]
3082 if {$olds ne {}} {
3083 set rmx [drawparentlinks $id $row $col $olds]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003084 } else {
3085 set rmx 0
3086 }
3087 drawcmittext $id $row $col $rmx
3088 set iddrawn($id) 1
3089}
3090
3091proc drawfrac {f0 f1} {
3092 global numcommits canv
3093 global linespc
3094
3095 set ymax [lindex [$canv cget -scrollregion] 3]
3096 if {$ymax eq {} || $ymax == 0} return
3097 set y0 [expr {int($f0 * $ymax)}]
3098 set row [expr {int(($y0 - 3) / $linespc) - 1}]
3099 if {$row < 0} {
3100 set row 0
3101 }
3102 set y1 [expr {int($f1 * $ymax)}]
3103 set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
3104 if {$endrow >= $numcommits} {
3105 set endrow [expr {$numcommits - 1}]
3106 }
3107 for {} {$row <= $endrow} {incr row} {
3108 drawcmitrow $row
3109 }
3110}
3111
3112proc drawvisible {} {
3113 global canv
3114 eval drawfrac [$canv yview]
3115}
3116
3117proc clear_display {} {
3118 global iddrawn idrangedrawn
Paul Mackerras164ff272006-05-29 19:50:02 +10003119 global vhighlights fhighlights nhighlights rhighlights
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003120
3121 allcanvs delete all
3122 catch {unset iddrawn}
3123 catch {unset idrangedrawn}
Paul Mackerras908c3582006-05-20 09:38:11 +10003124 catch {unset vhighlights}
3125 catch {unset fhighlights}
3126 catch {unset nhighlights}
Paul Mackerras164ff272006-05-29 19:50:02 +10003127 catch {unset rhighlights}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003128}
3129
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003130proc findcrossings {id} {
3131 global rowidlist parentlist numcommits rowoffsets displayorder
3132
3133 set cross {}
3134 set ccross {}
3135 foreach {s e} [rowranges $id] {
3136 if {$e >= $numcommits} {
3137 set e [expr {$numcommits - 1}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003138 }
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003139 if {$e <= $s} continue
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003140 set x [lsearch -exact [lindex $rowidlist $e] $id]
3141 if {$x < 0} {
3142 puts "findcrossings: oops, no [shortids $id] in row $e"
3143 continue
3144 }
3145 for {set row $e} {[incr row -1] >= $s} {} {
3146 set olds [lindex $parentlist $row]
3147 set kid [lindex $displayorder $row]
3148 set kidx [lsearch -exact [lindex $rowidlist $row] $kid]
3149 if {$kidx < 0} continue
3150 set nextrow [lindex $rowidlist [expr {$row + 1}]]
3151 foreach p $olds {
3152 set px [lsearch -exact $nextrow $p]
3153 if {$px < 0} continue
3154 if {($kidx < $x && $x < $px) || ($px < $x && $x < $kidx)} {
3155 if {[lsearch -exact $ccross $p] >= 0} continue
3156 if {$x == $px + ($kidx < $px? -1: 1)} {
3157 lappend ccross $p
3158 } elseif {[lsearch -exact $cross $p] < 0} {
3159 lappend cross $p
3160 }
3161 }
3162 }
3163 set inc [lindex $rowoffsets $row $x]
3164 if {$inc eq {}} break
3165 incr x $inc
3166 }
3167 }
3168 return [concat $ccross {{}} $cross]
3169}
3170
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003171proc assigncolor {id} {
Paul Mackerrasaa81d972006-02-28 11:27:12 +11003172 global colormap colors nextcolor
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003173 global commitrow parentlist children children curview
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003174
Paul Mackerras418c4c72006-02-07 09:10:18 +11003175 if {[info exists colormap($id)]} return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003176 set ncolors [llength $colors]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003177 if {[info exists children($curview,$id)]} {
3178 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 20:47:40 +10003179 } else {
3180 set kids {}
3181 }
3182 if {[llength $kids] == 1} {
3183 set child [lindex $kids 0]
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003184 if {[info exists colormap($child)]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003185 && [llength [lindex $parentlist $commitrow($curview,$child)]] == 1} {
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003186 set colormap($id) $colormap($child)
3187 return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003188 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003189 }
3190 set badcolors {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003191 set origbad {}
3192 foreach x [findcrossings $id] {
3193 if {$x eq {}} {
3194 # delimiter between corner crossings and other crossings
3195 if {[llength $badcolors] >= $ncolors - 1} break
3196 set origbad $badcolors
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003197 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003198 if {[info exists colormap($x)]
3199 && [lsearch -exact $badcolors $colormap($x)] < 0} {
3200 lappend badcolors $colormap($x)
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003201 }
3202 }
Paul Mackerras50b44ec2006-04-04 10:16:22 +10003203 if {[llength $badcolors] >= $ncolors} {
3204 set badcolors $origbad
3205 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003206 set origbad $badcolors
3207 if {[llength $badcolors] < $ncolors - 1} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003208 foreach child $kids {
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003209 if {[info exists colormap($child)]
3210 && [lsearch -exact $badcolors $colormap($child)] < 0} {
3211 lappend badcolors $colormap($child)
3212 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003213 foreach p [lindex $parentlist $commitrow($curview,$child)] {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003214 if {[info exists colormap($p)]
3215 && [lsearch -exact $badcolors $colormap($p)] < 0} {
3216 lappend badcolors $colormap($p)
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003217 }
3218 }
3219 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10003220 if {[llength $badcolors] >= $ncolors} {
3221 set badcolors $origbad
3222 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003223 }
3224 for {set i 0} {$i <= $ncolors} {incr i} {
3225 set c [lindex $colors $nextcolor]
3226 if {[incr nextcolor] >= $ncolors} {
3227 set nextcolor 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00003228 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003229 if {[lsearch -exact $badcolors $c]} break
3230 }
3231 set colormap($id) $c
3232}
3233
Paul Mackerrasa823a912005-06-21 10:01:38 +10003234proc bindline {t id} {
3235 global canv
3236
Paul Mackerrasa823a912005-06-21 10:01:38 +10003237 $canv bind $t <Enter> "lineenter %x %y $id"
3238 $canv bind $t <Motion> "linemotion %x %y $id"
3239 $canv bind $t <Leave> "lineleave $id"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003240 $canv bind $t <Button-1> "lineclick %x %y $id 1"
Paul Mackerrasa823a912005-06-21 10:01:38 +10003241}
3242
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003243proc drawtags {id x xt y1} {
Paul Mackerras8a485712006-07-06 10:21:23 +10003244 global idtags idheads idotherrefs mainhead
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003245 global linespc lthickness
Paul Mackerras8a485712006-07-06 10:21:23 +10003246 global canv mainfont commitrow rowtextx curview fgcolor bgcolor
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003247
3248 set marks {}
3249 set ntags 0
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003250 set nheads 0
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003251 if {[info exists idtags($id)]} {
3252 set marks $idtags($id)
3253 set ntags [llength $marks]
3254 }
3255 if {[info exists idheads($id)]} {
3256 set marks [concat $marks $idheads($id)]
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003257 set nheads [llength $idheads($id)]
3258 }
3259 if {[info exists idotherrefs($id)]} {
3260 set marks [concat $marks $idotherrefs($id)]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003261 }
3262 if {$marks eq {}} {
3263 return $xt
3264 }
3265
3266 set delta [expr {int(0.5 * ($linespc - $lthickness))}]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003267 set yt [expr {$y1 - 0.5 * $linespc}]
3268 set yb [expr {$yt + $linespc - 1}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003269 set xvals {}
3270 set wvals {}
Paul Mackerras8a485712006-07-06 10:21:23 +10003271 set i -1
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003272 foreach tag $marks {
Paul Mackerras8a485712006-07-06 10:21:23 +10003273 incr i
3274 if {$i >= $ntags && $i < $ntags + $nheads && $tag eq $mainhead} {
3275 set wid [font measure [concat $mainfont bold] $tag]
3276 } else {
3277 set wid [font measure $mainfont $tag]
3278 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003279 lappend xvals $xt
3280 lappend wvals $wid
3281 set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
3282 }
3283 set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
3284 -width $lthickness -fill black -tags tag.$id]
3285 $canv lower $t
3286 foreach tag $marks x $xvals wid $wvals {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003287 set xl [expr {$x + $delta}]
3288 set xr [expr {$x + $delta + $wid + $lthickness}]
Paul Mackerras8a485712006-07-06 10:21:23 +10003289 set font $mainfont
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003290 if {[incr ntags -1] >= 0} {
3291 # draw a tag
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003292 set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
3293 $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
Paul Mackerras106288c2005-08-19 23:11:39 +10003294 -width 1 -outline black -fill yellow -tags tag.$id]
3295 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003296 set rowtextx($commitrow($curview,$id)) [expr {$xr + $linespc}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003297 } else {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003298 # draw a head or other ref
3299 if {[incr nheads -1] >= 0} {
3300 set col green
Paul Mackerras8a485712006-07-06 10:21:23 +10003301 if {$tag eq $mainhead} {
3302 lappend font bold
3303 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003304 } else {
3305 set col "#ddddff"
3306 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003307 set xl [expr {$xl - $delta/2}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003308 $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003309 -width 1 -outline black -fill $col -tags tag.$id
Josef Weidendorfera970fcf2006-04-18 23:53:07 +02003310 if {[regexp {^(remotes/.*/|remotes/)} $tag match remoteprefix]} {
3311 set rwid [font measure $mainfont $remoteprefix]
3312 set xi [expr {$x + 1}]
3313 set yti [expr {$yt + 1}]
3314 set xri [expr {$x + $rwid}]
3315 $canv create polygon $xi $yti $xri $yti $xri $yb $xi $yb \
3316 -width 0 -fill "#ffddaa" -tags tag.$id
3317 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003318 }
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003319 set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \
Paul Mackerras8a485712006-07-06 10:21:23 +10003320 -font $font -tags [list tag.$id text]]
Paul Mackerras106288c2005-08-19 23:11:39 +10003321 if {$ntags >= 0} {
3322 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerras10299152006-08-02 09:52:01 +10003323 } elseif {$nheads >= 0} {
3324 $canv bind $t <Button-3> [list headmenu %X %Y $id $tag]
Paul Mackerras106288c2005-08-19 23:11:39 +10003325 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003326 }
3327 return $xt
3328}
3329
Paul Mackerras8d858d12005-08-05 09:52:16 +10003330proc xcoord {i level ln} {
3331 global canvx0 xspc1 xspc2
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003332
Paul Mackerras8d858d12005-08-05 09:52:16 +10003333 set x [expr {$canvx0 + $i * $xspc1($ln)}]
3334 if {$i > 0 && $i == $level} {
3335 set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
3336 } elseif {$i > $level} {
3337 set x [expr {$x + $xspc2 - $xspc1($ln)}]
3338 }
3339 return $x
3340}
3341
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003342proc show_status {msg} {
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003343 global canv mainfont fgcolor
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003344
3345 clear_display
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10003346 $canv create text 3 3 -anchor nw -text $msg -font $mainfont \
3347 -tags text -fill $fgcolor
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003348}
3349
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003350proc finishcommits {} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003351 global commitidx phase curview
Paul Mackerrase1a7c812006-07-18 01:52:14 +10003352 global pending_select
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003353
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003354 if {$commitidx($curview) > 0} {
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01003355 drawrest
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01003356 } else {
Paul Mackerras098dd8a2006-05-03 09:32:53 +10003357 show_status "No commits selected"
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003358 }
Paul Mackerras8ed16482006-03-02 22:56:44 +11003359 set phase {}
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003360 catch {unset pending_select}
Paul Mackerras94a2eed2005-08-07 15:27:57 +10003361}
3362
Paul Mackerras561d0382006-08-28 22:41:09 +10003363# Insert a new commit as the child of the commit on row $row.
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003364# The new commit will be displayed on row $row and the commits
3365# on that row and below will move down one row.
3366proc insertrow {row newcmit} {
3367 global displayorder parentlist childlist commitlisted
3368 global commitrow curview rowidlist rowoffsets numcommits
3369 global rowrangelist idrowranges rowlaidout rowoptim numcommits
Paul Mackerras561d0382006-08-28 22:41:09 +10003370 global linesegends selectedline
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003371
3372 if {$row >= $numcommits} {
3373 puts "oops, inserting new row $row but only have $numcommits rows"
3374 return
3375 }
3376 set p [lindex $displayorder $row]
3377 set displayorder [linsert $displayorder $row $newcmit]
3378 set parentlist [linsert $parentlist $row $p]
3379 set kids [lindex $childlist $row]
3380 lappend kids $newcmit
3381 lset childlist $row $kids
3382 set childlist [linsert $childlist $row {}]
Paul Mackerras561d0382006-08-28 22:41:09 +10003383 set commitlisted [linsert $commitlisted $row 1]
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003384 set l [llength $displayorder]
3385 for {set r $row} {$r < $l} {incr r} {
3386 set id [lindex $displayorder $r]
3387 set commitrow($curview,$id) $r
3388 }
3389
3390 set idlist [lindex $rowidlist $row]
3391 set offs [lindex $rowoffsets $row]
3392 set newoffs {}
3393 foreach x $idlist {
3394 if {$x eq {} || ($x eq $p && [llength $kids] == 1)} {
3395 lappend newoffs {}
3396 } else {
3397 lappend newoffs 0
3398 }
3399 }
3400 if {[llength $kids] == 1} {
3401 set col [lsearch -exact $idlist $p]
3402 lset idlist $col $newcmit
3403 } else {
3404 set col [llength $idlist]
3405 lappend idlist $newcmit
3406 lappend offs {}
3407 lset rowoffsets $row $offs
3408 }
3409 set rowidlist [linsert $rowidlist $row $idlist]
3410 set rowoffsets [linsert $rowoffsets [expr {$row+1}] $newoffs]
3411
3412 set rowrangelist [linsert $rowrangelist $row {}]
3413 set l [llength $rowrangelist]
3414 for {set r 0} {$r < $l} {incr r} {
3415 set ranges [lindex $rowrangelist $r]
3416 if {$ranges ne {} && [lindex $ranges end] >= $row} {
3417 set newranges {}
3418 foreach x $ranges {
3419 if {$x >= $row} {
3420 lappend newranges [expr {$x + 1}]
3421 } else {
3422 lappend newranges $x
3423 }
3424 }
3425 lset rowrangelist $r $newranges
3426 }
3427 }
3428 if {[llength $kids] > 1} {
3429 set rp1 [expr {$row + 1}]
3430 set ranges [lindex $rowrangelist $rp1]
3431 if {$ranges eq {}} {
3432 set ranges [list $row $rp1]
3433 } elseif {[lindex $ranges end-1] == $rp1} {
3434 lset ranges end-1 $row
3435 }
3436 lset rowrangelist $rp1 $ranges
3437 }
3438 foreach id [array names idrowranges] {
3439 set ranges $idrowranges($id)
3440 if {$ranges ne {} && [lindex $ranges end] >= $row} {
3441 set newranges {}
3442 foreach x $ranges {
3443 if {$x >= $row} {
3444 lappend newranges [expr {$x + 1}]
3445 } else {
3446 lappend newranges $x
3447 }
3448 }
3449 set idrowranges($id) $newranges
3450 }
3451 }
3452
3453 set linesegends [linsert $linesegends $row {}]
3454
3455 incr rowlaidout
3456 incr rowoptim
3457 incr numcommits
3458
Paul Mackerras561d0382006-08-28 22:41:09 +10003459 if {[info exists selectedline] && $selectedline >= $row} {
3460 incr selectedline
3461 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003462 redisplay
3463}
3464
Paul Mackerras94a2eed2005-08-07 15:27:57 +10003465# Don't change the text pane cursor if it is currently the hand cursor,
3466# showing that we are over a sha1 ID link.
3467proc settextcursor {c} {
3468 global ctext curtextcursor
3469
3470 if {[$ctext cget -cursor] == $curtextcursor} {
3471 $ctext config -cursor $c
3472 }
3473 set curtextcursor $c
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003474}
3475
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003476proc nowbusy {what} {
3477 global isbusy
3478
3479 if {[array names isbusy] eq {}} {
3480 . config -cursor watch
3481 settextcursor watch
3482 }
3483 set isbusy($what) 1
3484}
3485
3486proc notbusy {what} {
3487 global isbusy maincursor textcursor
3488
3489 catch {unset isbusy($what)}
3490 if {[array names isbusy] eq {}} {
3491 . config -cursor $maincursor
3492 settextcursor $textcursor
3493 }
3494}
3495
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10003496proc drawrest {} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003497 global startmsecs
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003498 global rowlaidout commitidx curview
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003499 global pending_select
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00003500
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003501 set row $rowlaidout
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003502 layoutrows $rowlaidout $commitidx($curview) 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003503 layouttail
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003504 optimize_rows $row 0 $commitidx($curview)
3505 showstuff $commitidx($curview)
Paul Mackerrasfdedbcf2006-04-06 21:22:52 +10003506 if {[info exists pending_select]} {
3507 selectline 0 1
3508 }
Paul Mackerras4dd5d0d2005-12-06 09:46:23 +11003509
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003510 set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}]
Paul Mackerrase1a7c812006-07-18 01:52:14 +10003511 #global numcommits
Paul Mackerras4e95e1f2006-04-05 09:39:51 +10003512 #puts "overall $drawmsecs ms for $numcommits commits"
Paul Mackerras1db95b02005-05-09 04:08:39 +00003513}
3514
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003515proc findmatches {f} {
3516 global findtype foundstring foundstrlen
3517 if {$findtype == "Regexp"} {
3518 set matches [regexp -indices -all -inline $foundstring $f]
3519 } else {
3520 if {$findtype == "IgnCase"} {
3521 set str [string tolower $f]
3522 } else {
3523 set str $f
3524 }
3525 set matches {}
3526 set i 0
3527 while {[set j [string first $foundstring $str $i]] >= 0} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003528 lappend matches [list $j [expr {$j+$foundstrlen-1}]]
3529 set i [expr {$j + $foundstrlen}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003530 }
3531 }
3532 return $matches
3533}
3534
Paul Mackerras98f350e2005-05-15 05:56:51 +00003535proc dofind {} {
3536 global findtype findloc findstring markedmatches commitinfo
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003537 global numcommits displayorder linehtag linentag linedtag
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003538 global mainfont canv canv2 canv3 selectedline
Paul Mackerras8ed16482006-03-02 22:56:44 +11003539 global matchinglines foundstring foundstrlen matchstring
3540 global commitdata
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003541
3542 stopfindproc
Paul Mackerras98f350e2005-05-15 05:56:51 +00003543 unmarkmatches
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003544 cancel_next_highlight
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003545 focus .
Paul Mackerras98f350e2005-05-15 05:56:51 +00003546 set matchinglines {}
Paul Mackerras98f350e2005-05-15 05:56:51 +00003547 if {$findtype == "IgnCase"} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003548 set foundstring [string tolower $findstring]
Paul Mackerras98f350e2005-05-15 05:56:51 +00003549 } else {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003550 set foundstring $findstring
Paul Mackerras98f350e2005-05-15 05:56:51 +00003551 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003552 set foundstrlen [string length $findstring]
3553 if {$foundstrlen == 0} return
Paul Mackerras8ed16482006-03-02 22:56:44 +11003554 regsub -all {[*?\[\\]} $foundstring {\\&} matchstring
3555 set matchstring "*$matchstring*"
Paul Mackerras98f350e2005-05-15 05:56:51 +00003556 if {![info exists selectedline]} {
3557 set oldsel -1
3558 } else {
3559 set oldsel $selectedline
3560 }
3561 set didsel 0
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10003562 set fldtypes {Headline Author Date Committer CDate Comments}
Paul Mackerras8ed16482006-03-02 22:56:44 +11003563 set l -1
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11003564 foreach id $displayorder {
3565 set d $commitdata($id)
Paul Mackerras8ed16482006-03-02 22:56:44 +11003566 incr l
3567 if {$findtype == "Regexp"} {
3568 set doesmatch [regexp $foundstring $d]
3569 } elseif {$findtype == "IgnCase"} {
3570 set doesmatch [string match -nocase $matchstring $d]
3571 } else {
3572 set doesmatch [string match $matchstring $d]
3573 }
3574 if {!$doesmatch} continue
Paul Mackerras8ed16482006-03-02 22:56:44 +11003575 if {![info exists commitinfo($id)]} {
Paul Mackerrasf7a3e8d2006-03-18 10:04:48 +11003576 getcommit $id
Paul Mackerras8ed16482006-03-02 22:56:44 +11003577 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003578 set info $commitinfo($id)
3579 set doesmatch 0
3580 foreach f $info ty $fldtypes {
3581 if {$findloc != "All fields" && $findloc != $ty} {
3582 continue
3583 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003584 set matches [findmatches $f]
Paul Mackerras98f350e2005-05-15 05:56:51 +00003585 if {$matches == {}} continue
3586 set doesmatch 1
3587 if {$ty == "Headline"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003588 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003589 markmatches $canv $l $f $linehtag($l) $matches $mainfont
3590 } elseif {$ty == "Author"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003591 drawcmitrow $l
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003592 markmatches $canv2 $l $f $linentag($l) $matches $mainfont
Paul Mackerras98f350e2005-05-15 05:56:51 +00003593 } elseif {$ty == "Date"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003594 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003595 markmatches $canv3 $l $f $linedtag($l) $matches $mainfont
3596 }
3597 }
3598 if {$doesmatch} {
3599 lappend matchinglines $l
3600 if {!$didsel && $l > $oldsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003601 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003602 set didsel 1
3603 }
3604 }
3605 }
3606 if {$matchinglines == {}} {
3607 bell
3608 } elseif {!$didsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003609 findselectline [lindex $matchinglines 0]
3610 }
3611}
3612
3613proc findselectline {l} {
3614 global findloc commentend ctext
Paul Mackerrasd6982062005-08-06 22:06:06 +10003615 selectline $l 1
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003616 if {$findloc == "All fields" || $findloc == "Comments"} {
3617 # highlight the matches in the comments
3618 set f [$ctext get 1.0 $commentend]
3619 set matches [findmatches $f]
3620 foreach match $matches {
3621 set start [lindex $match 0]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003622 set end [expr {[lindex $match 1] + 1}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003623 $ctext tag add found "1.0 + $start c" "1.0 + $end c"
3624 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003625 }
3626}
3627
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003628proc findnext {restart} {
Paul Mackerras98f350e2005-05-15 05:56:51 +00003629 global matchinglines selectedline
3630 if {![info exists matchinglines]} {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003631 if {$restart} {
3632 dofind
3633 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003634 return
3635 }
3636 if {![info exists selectedline]} return
3637 foreach l $matchinglines {
3638 if {$l > $selectedline} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003639 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00003640 return
3641 }
3642 }
3643 bell
3644}
3645
3646proc findprev {} {
3647 global matchinglines selectedline
3648 if {![info exists matchinglines]} {
3649 dofind
3650 return
3651 }
3652 if {![info exists selectedline]} return
3653 set prev {}
3654 foreach l $matchinglines {
3655 if {$l >= $selectedline} break
3656 set prev $l
3657 }
3658 if {$prev != {}} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00003659 findselectline $prev
Paul Mackerras98f350e2005-05-15 05:56:51 +00003660 } else {
3661 bell
3662 }
3663}
3664
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003665proc stopfindproc {{done 0}} {
3666 global findprocpid findprocfile findids
3667 global ctext findoldcursor phase maincursor textcursor
3668 global findinprogress
3669
3670 catch {unset findids}
3671 if {[info exists findprocpid]} {
3672 if {!$done} {
3673 catch {exec kill $findprocpid}
3674 }
3675 catch {close $findprocfile}
3676 unset findprocpid
3677 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003678 catch {unset findinprogress}
3679 notbusy find
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003680}
3681
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003682# mark a commit as matching by putting a yellow background
3683# behind the headline
3684proc markheadline {l id} {
Paul Mackerras8ed16482006-03-02 22:56:44 +11003685 global canv mainfont linehtag
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003686
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003687 drawcmitrow $l
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003688 set bbox [$canv bbox $linehtag($l)]
3689 set t [$canv create rect $bbox -outline {} -tags matches -fill yellow]
3690 $canv lower $t
3691}
3692
3693# mark the bits of a headline, author or date that match a find string
Paul Mackerras98f350e2005-05-15 05:56:51 +00003694proc markmatches {canv l str tag matches font} {
3695 set bbox [$canv bbox $tag]
3696 set x0 [lindex $bbox 0]
3697 set y0 [lindex $bbox 1]
3698 set y1 [lindex $bbox 3]
3699 foreach match $matches {
3700 set start [lindex $match 0]
3701 set end [lindex $match 1]
3702 if {$start > $end} continue
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003703 set xoff [font measure $font [string range $str 0 [expr {$start-1}]]]
3704 set xlen [font measure $font [string range $str 0 [expr {$end}]]]
3705 set t [$canv create rect [expr {$x0+$xoff}] $y0 \
3706 [expr {$x0+$xlen+2}] $y1 \
Paul Mackerras98f350e2005-05-15 05:56:51 +00003707 -outline {} -tags matches -fill yellow]
3708 $canv lower $t
3709 }
3710}
3711
3712proc unmarkmatches {} {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003713 global matchinglines findids
Paul Mackerras98f350e2005-05-15 05:56:51 +00003714 allcanvs delete matches
3715 catch {unset matchinglines}
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003716 catch {unset findids}
Paul Mackerras98f350e2005-05-15 05:56:51 +00003717}
3718
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003719proc selcanvline {w x y} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003720 global canv canvy0 ctext linespc
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003721 global rowtextx
Paul Mackerras1db95b02005-05-09 04:08:39 +00003722 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerrascfb45632005-05-31 12:14:42 +00003723 if {$ymax == {}} return
Paul Mackerras1db95b02005-05-09 04:08:39 +00003724 set yfrac [lindex [$canv yview] 0]
3725 set y [expr {$y + $yfrac * $ymax}]
3726 set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
3727 if {$l < 0} {
3728 set l 0
3729 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003730 if {$w eq $canv} {
3731 if {![info exists rowtextx($l)] || $x < $rowtextx($l)} return
3732 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00003733 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10003734 selectline $l 1
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003735}
3736
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003737proc commit_descriptor {p} {
3738 global commitinfo
Paul Mackerrasb0934482006-05-15 09:56:08 +10003739 if {![info exists commitinfo($p)]} {
3740 getcommit $p
3741 }
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003742 set l "..."
Paul Mackerrasb0934482006-05-15 09:56:08 +10003743 if {[llength $commitinfo($p)] > 1} {
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003744 set l [lindex $commitinfo($p) 0]
3745 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003746 return "$p ($l)\n"
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003747}
3748
Paul Mackerras106288c2005-08-19 23:11:39 +10003749# append some text to the ctext widget, and make any SHA1 ID
3750# that we know about be a clickable link.
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003751proc appendwithlinks {text tags} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003752 global ctext commitrow linknum curview
Paul Mackerras106288c2005-08-19 23:11:39 +10003753
3754 set start [$ctext index "end - 1c"]
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003755 $ctext insert end $text $tags
Paul Mackerras106288c2005-08-19 23:11:39 +10003756 set links [regexp -indices -all -inline {[0-9a-f]{40}} $text]
3757 foreach l $links {
3758 set s [lindex $l 0]
3759 set e [lindex $l 1]
3760 set linkid [string range $text $s $e]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003761 if {![info exists commitrow($curview,$linkid)]} continue
Paul Mackerras106288c2005-08-19 23:11:39 +10003762 incr e
3763 $ctext tag add link "$start + $s c" "$start + $e c"
3764 $ctext tag add link$linknum "$start + $s c" "$start + $e c"
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10003765 $ctext tag bind link$linknum <1> \
3766 [list selectline $commitrow($curview,$linkid) 1]
Paul Mackerras106288c2005-08-19 23:11:39 +10003767 incr linknum
3768 }
3769 $ctext tag conf link -foreground blue -underline 1
3770 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
3771 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
3772}
3773
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10003774proc viewnextline {dir} {
3775 global canv linespc
3776
3777 $canv delete hover
3778 set ymax [lindex [$canv cget -scrollregion] 3]
3779 set wnow [$canv yview]
3780 set wtop [expr {[lindex $wnow 0] * $ymax}]
3781 set newtop [expr {$wtop + $dir * $linespc}]
3782 if {$newtop < 0} {
3783 set newtop 0
3784 } elseif {$newtop > $ymax} {
3785 set newtop $ymax
3786 }
3787 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
3788}
3789
Paul Mackerrasef030b82006-06-04 11:50:38 +10003790# add a list of tag or branch names at position pos
3791# returns the number of names inserted
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003792proc appendrefs {pos tags var} {
3793 global ctext commitrow linknum curview $var
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003794
Paul Mackerrasef030b82006-06-04 11:50:38 +10003795 if {[catch {$ctext index $pos}]} {
3796 return 0
3797 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003798 set tags [lsort $tags]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003799 set sep {}
3800 foreach tag $tags {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003801 set id [set $var\($tag\)]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003802 set lk link$linknum
3803 incr linknum
3804 $ctext insert $pos $sep
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003805 $ctext insert $pos $tag $lk
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003806 $ctext tag conf $lk -foreground blue
3807 if {[info exists commitrow($curview,$id)]} {
3808 $ctext tag bind $lk <1> \
3809 [list selectline $commitrow($curview,$id) 1]
3810 $ctext tag conf $lk -underline 1
3811 $ctext tag bind $lk <Enter> { %W configure -cursor hand2 }
3812 $ctext tag bind $lk <Leave> { %W configure -cursor $curtextcursor }
3813 }
3814 set sep ", "
3815 }
Paul Mackerrasef030b82006-06-04 11:50:38 +10003816 return [llength $tags]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003817}
3818
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003819proc taglist {ids} {
3820 global idtags
3821
3822 set tags {}
3823 foreach id $ids {
3824 foreach tag $idtags($id) {
3825 lappend tags $tag
3826 }
3827 }
3828 return $tags
3829}
3830
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003831# called when we have finished computing the nearby tags
3832proc dispneartags {} {
3833 global selectedline currentid ctext anc_tags desc_tags showneartags
Paul Mackerrasef030b82006-06-04 11:50:38 +10003834 global desc_heads
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003835
3836 if {![info exists selectedline] || !$showneartags} return
3837 set id $currentid
3838 $ctext conf -state normal
Paul Mackerrasef030b82006-06-04 11:50:38 +10003839 if {[info exists desc_heads($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003840 if {[appendrefs branch $desc_heads($id) headids] > 1} {
Paul Mackerrasef030b82006-06-04 11:50:38 +10003841 $ctext insert "branch -2c" "es"
3842 }
3843 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003844 if {[info exists anc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003845 appendrefs follows [taglist $anc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003846 }
3847 if {[info exists desc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003848 appendrefs precedes [taglist $desc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003849 }
3850 $ctext conf -state disabled
3851}
3852
Paul Mackerrasd6982062005-08-06 22:06:06 +10003853proc selectline {l isnew} {
Paul Mackerrasd2610d12005-05-11 00:45:38 +00003854 global canv canv2 canv3 ctext commitinfo selectedline
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003855 global displayorder linehtag linentag linedtag
Paul Mackerras79b2c752006-04-02 20:47:40 +10003856 global canvy0 linespc parentlist childlist
Paul Mackerras7fcceed2006-04-27 19:21:49 +10003857 global currentid sha1entry
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003858 global commentend idtags linknum
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003859 global mergemax numcommits pending_select
Paul Mackerrasef030b82006-06-04 11:50:38 +10003860 global cmitmode desc_tags anc_tags showneartags allcommits desc_heads
Paul Mackerrasd6982062005-08-06 22:06:06 +10003861
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10003862 catch {unset pending_select}
Paul Mackerras84ba7342005-06-17 00:12:26 +00003863 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10003864 normalline
Paul Mackerras4e7d6772006-05-30 21:33:07 +10003865 cancel_next_highlight
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003866 if {$l < 0 || $l >= $numcommits} return
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003867 set y [expr {$canvy0 + $l * $linespc}]
Paul Mackerras17386062005-05-18 22:51:00 +00003868 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerras58422152005-05-19 10:56:42 +00003869 set ytop [expr {$y - $linespc - 1}]
3870 set ybot [expr {$y + $linespc + 1}]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003871 set wnow [$canv yview]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003872 set wtop [expr {[lindex $wnow 0] * $ymax}]
3873 set wbot [expr {[lindex $wnow 1] * $ymax}]
Paul Mackerras58422152005-05-19 10:56:42 +00003874 set wh [expr {$wbot - $wtop}]
3875 set newtop $wtop
Paul Mackerras17386062005-05-18 22:51:00 +00003876 if {$ytop < $wtop} {
Paul Mackerras58422152005-05-19 10:56:42 +00003877 if {$ybot < $wtop} {
3878 set newtop [expr {$y - $wh / 2.0}]
3879 } else {
3880 set newtop $ytop
3881 if {$newtop > $wtop - $linespc} {
3882 set newtop [expr {$wtop - $linespc}]
3883 }
Paul Mackerras17386062005-05-18 22:51:00 +00003884 }
Paul Mackerras58422152005-05-19 10:56:42 +00003885 } elseif {$ybot > $wbot} {
3886 if {$ytop > $wbot} {
3887 set newtop [expr {$y - $wh / 2.0}]
3888 } else {
3889 set newtop [expr {$ybot - $wh}]
3890 if {$newtop < $wtop + $linespc} {
3891 set newtop [expr {$wtop + $linespc}]
3892 }
Paul Mackerras17386062005-05-18 22:51:00 +00003893 }
Paul Mackerras58422152005-05-19 10:56:42 +00003894 }
3895 if {$newtop != $wtop} {
3896 if {$newtop < 0} {
3897 set newtop 0
3898 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08003899 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003900 drawvisible
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003901 }
Paul Mackerrasd6982062005-08-06 22:06:06 +10003902
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003903 if {![info exists linehtag($l)]} return
3904 $canv delete secsel
3905 set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
3906 -tags secsel -fill [$canv cget -selectbackground]]
3907 $canv lower $t
3908 $canv2 delete secsel
3909 set t [eval $canv2 create rect [$canv2 bbox $linentag($l)] -outline {{}} \
3910 -tags secsel -fill [$canv2 cget -selectbackground]]
3911 $canv2 lower $t
3912 $canv3 delete secsel
3913 set t [eval $canv3 create rect [$canv3 bbox $linedtag($l)] -outline {{}} \
3914 -tags secsel -fill [$canv3 cget -selectbackground]]
3915 $canv3 lower $t
3916
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003917 if {$isnew} {
3918 addtohistory [list selectline $l 0]
Paul Mackerrasd6982062005-08-06 22:06:06 +10003919 }
3920
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003921 set selectedline $l
3922
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11003923 set id [lindex $displayorder $l]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00003924 set currentid $id
Paul Mackerras98f350e2005-05-15 05:56:51 +00003925 $sha1entry delete 0 end
3926 $sha1entry insert 0 $id
3927 $sha1entry selection from 0
3928 $sha1entry selection to end
Paul Mackerras164ff272006-05-29 19:50:02 +10003929 rhighlight_sel $id
Paul Mackerras98f350e2005-05-15 05:56:51 +00003930
Paul Mackerras5ad588d2005-05-10 01:02:55 +00003931 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10003932 clear_ctext
Paul Mackerras106288c2005-08-19 23:11:39 +10003933 set linknum 0
Paul Mackerras1db95b02005-05-09 04:08:39 +00003934 set info $commitinfo($id)
Paul Mackerras232475d2005-11-15 10:34:03 +11003935 set date [formatdate [lindex $info 2]]
3936 $ctext insert end "Author: [lindex $info 1] $date\n"
3937 set date [formatdate [lindex $info 4]]
3938 $ctext insert end "Committer: [lindex $info 3] $date\n"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00003939 if {[info exists idtags($id)]} {
3940 $ctext insert end "Tags:"
3941 foreach tag $idtags($id) {
3942 $ctext insert end " $tag"
3943 }
3944 $ctext insert end "\n"
3945 }
Mark Levedahl40b87ff2007-02-01 08:44:46 -05003946
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003947 set headers {}
Paul Mackerras79b2c752006-04-02 20:47:40 +10003948 set olds [lindex $parentlist $l]
3949 if {[llength $olds] > 1} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003950 set np 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10003951 foreach p $olds {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003952 if {$np >= $mergemax} {
3953 set tag mmax
3954 } else {
3955 set tag m$np
3956 }
3957 $ctext insert end "Parent: " $tag
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003958 appendwithlinks [commit_descriptor $p] {}
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003959 incr np
3960 }
3961 } else {
Paul Mackerras79b2c752006-04-02 20:47:40 +10003962 foreach p $olds {
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003963 append headers "Parent: [commit_descriptor $p]"
Linus Torvalds8b192802005-08-07 13:58:56 -07003964 }
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07003965 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11003966
Paul Mackerras79b2c752006-04-02 20:47:40 +10003967 foreach c [lindex $childlist $l] {
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003968 append headers "Child: [commit_descriptor $c]"
Linus Torvalds8b192802005-08-07 13:58:56 -07003969 }
Paul Mackerrasd6982062005-08-06 22:06:06 +10003970
3971 # make anything that looks like a SHA1 ID be a clickable link
Sergey Vlasovf1b86292006-05-15 19:13:14 +04003972 appendwithlinks $headers {}
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003973 if {$showneartags} {
3974 if {![info exists allcommits]} {
3975 getallcommits
3976 }
Paul Mackerrasef030b82006-06-04 11:50:38 +10003977 $ctext insert end "Branch: "
3978 $ctext mark set branch "end -1c"
3979 $ctext mark gravity branch left
3980 if {[info exists desc_heads($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003981 if {[appendrefs branch $desc_heads($id) headids] > 1} {
Paul Mackerrasef030b82006-06-04 11:50:38 +10003982 # turn "Branch" into "Branches"
3983 $ctext insert "branch -2c" "es"
3984 }
3985 }
3986 $ctext insert end "\nFollows: "
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003987 $ctext mark set follows "end -1c"
3988 $ctext mark gravity follows left
3989 if {[info exists anc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003990 appendrefs follows [taglist $anc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003991 }
3992 $ctext insert end "\nPrecedes: "
3993 $ctext mark set precedes "end -1c"
3994 $ctext mark gravity precedes left
3995 if {[info exists desc_tags($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10003996 appendrefs precedes [taglist $desc_tags($id)] tagids
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10003997 }
3998 $ctext insert end "\n"
3999 }
4000 $ctext insert end "\n"
Sergey Vlasovf1b86292006-05-15 19:13:14 +04004001 appendwithlinks [lindex $info 5] {comment}
Paul Mackerrasd6982062005-08-06 22:06:06 +10004002
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004003 $ctext tag delete Comments
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00004004 $ctext tag remove found 1.0 end
Paul Mackerras5ad588d2005-05-10 01:02:55 +00004005 $ctext conf -state disabled
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00004006 set commentend [$ctext index "end - 1c"]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00004007
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004008 init_flist "Comments"
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004009 if {$cmitmode eq "tree"} {
4010 gettree $id
4011 } elseif {[llength $olds] <= 1} {
Paul Mackerrasd3272442005-11-28 20:41:56 +11004012 startdiff $id
Paul Mackerras7b5ff7e2006-03-30 20:50:40 +11004013 } else {
Paul Mackerras79b2c752006-04-02 20:47:40 +10004014 mergediff $id $l
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004015 }
4016}
4017
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004018proc selfirstline {} {
4019 unmarkmatches
4020 selectline 0 1
4021}
4022
4023proc sellastline {} {
4024 global numcommits
4025 unmarkmatches
4026 set l [expr {$numcommits - 1}]
4027 selectline $l 1
4028}
4029
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004030proc selnextline {dir} {
4031 global selectedline
4032 if {![info exists selectedline]} return
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08004033 set l [expr {$selectedline + $dir}]
Paul Mackerras98f350e2005-05-15 05:56:51 +00004034 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10004035 selectline $l 1
4036}
4037
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004038proc selnextpage {dir} {
4039 global canv linespc selectedline numcommits
4040
4041 set lpp [expr {([winfo height $canv] - 2) / $linespc}]
4042 if {$lpp < 1} {
4043 set lpp 1
4044 }
4045 allcanvs yview scroll [expr {$dir * $lpp}] units
Paul Mackerrase72ee5e2006-05-20 09:58:49 +10004046 drawvisible
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004047 if {![info exists selectedline]} return
4048 set l [expr {$selectedline + $dir * $lpp}]
4049 if {$l < 0} {
4050 set l 0
4051 } elseif {$l >= $numcommits} {
4052 set l [expr $numcommits - 1]
4053 }
4054 unmarkmatches
Mark Levedahl40b87ff2007-02-01 08:44:46 -05004055 selectline $l 1
Rutger Nijlunsing6e5f7202006-04-05 10:24:03 +10004056}
4057
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004058proc unselectline {} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004059 global selectedline currentid
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004060
4061 catch {unset selectedline}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004062 catch {unset currentid}
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004063 allcanvs delete secsel
Paul Mackerras164ff272006-05-29 19:50:02 +10004064 rhighlight_none
Paul Mackerras4e7d6772006-05-30 21:33:07 +10004065 cancel_next_highlight
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004066}
4067
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004068proc reselectline {} {
4069 global selectedline
4070
4071 if {[info exists selectedline]} {
4072 selectline $selectedline 0
4073 }
4074}
4075
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004076proc addtohistory {cmd} {
Paul Mackerras2516dae2006-04-21 10:35:31 +10004077 global history historyindex curview
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004078
Paul Mackerras2516dae2006-04-21 10:35:31 +10004079 set elt [list $curview $cmd]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004080 if {$historyindex > 0
Paul Mackerras2516dae2006-04-21 10:35:31 +10004081 && [lindex $history [expr {$historyindex - 1}]] == $elt} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004082 return
4083 }
4084
4085 if {$historyindex < [llength $history]} {
Paul Mackerras2516dae2006-04-21 10:35:31 +10004086 set history [lreplace $history $historyindex end $elt]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004087 } else {
Paul Mackerras2516dae2006-04-21 10:35:31 +10004088 lappend history $elt
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004089 }
4090 incr historyindex
4091 if {$historyindex > 1} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004092 .tf.bar.leftbut conf -state normal
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004093 } else {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004094 .tf.bar.leftbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004095 }
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004096 .tf.bar.rightbut conf -state disabled
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004097}
4098
Paul Mackerras2516dae2006-04-21 10:35:31 +10004099proc godo {elt} {
4100 global curview
4101
4102 set view [lindex $elt 0]
4103 set cmd [lindex $elt 1]
4104 if {$curview != $view} {
4105 showview $view
4106 }
4107 eval $cmd
4108}
4109
Paul Mackerrasd6982062005-08-06 22:06:06 +10004110proc goback {} {
4111 global history historyindex
4112
4113 if {$historyindex > 1} {
4114 incr historyindex -1
Paul Mackerras2516dae2006-04-21 10:35:31 +10004115 godo [lindex $history [expr {$historyindex - 1}]]
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004116 .tf.bar.rightbut conf -state normal
Paul Mackerrasd6982062005-08-06 22:06:06 +10004117 }
4118 if {$historyindex <= 1} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004119 .tf.bar.leftbut conf -state disabled
Paul Mackerrasd6982062005-08-06 22:06:06 +10004120 }
4121}
4122
4123proc goforw {} {
4124 global history historyindex
4125
4126 if {$historyindex < [llength $history]} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004127 set cmd [lindex $history $historyindex]
Paul Mackerrasd6982062005-08-06 22:06:06 +10004128 incr historyindex
Paul Mackerras2516dae2006-04-21 10:35:31 +10004129 godo $cmd
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004130 .tf.bar.leftbut conf -state normal
Paul Mackerrasd6982062005-08-06 22:06:06 +10004131 }
4132 if {$historyindex >= [llength $history]} {
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004133 .tf.bar.rightbut conf -state disabled
Paul Mackerrasd6982062005-08-06 22:06:06 +10004134 }
Paul Mackerras5ad588d2005-05-10 01:02:55 +00004135}
4136
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004137proc gettree {id} {
4138 global treefilelist treeidlist diffids diffmergeid treepending
4139
4140 set diffids $id
4141 catch {unset diffmergeid}
4142 if {![info exists treefilelist($id)]} {
4143 if {![info exists treepending]} {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004144 if {[catch {set gtf [open [concat | git ls-tree -r $id] r]}]} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004145 return
4146 }
4147 set treepending $id
4148 set treefilelist($id) {}
4149 set treeidlist($id) {}
4150 fconfigure $gtf -blocking 0
4151 fileevent $gtf readable [list gettreeline $gtf $id]
4152 }
4153 } else {
4154 setfilelist $id
4155 }
4156}
4157
4158proc gettreeline {gtf id} {
4159 global treefilelist treeidlist treepending cmitmode diffids
4160
4161 while {[gets $gtf line] >= 0} {
4162 if {[lindex $line 1] ne "blob"} continue
4163 set sha1 [lindex $line 2]
4164 set fname [lindex $line 3]
4165 lappend treefilelist($id) $fname
4166 lappend treeidlist($id) $sha1
4167 }
4168 if {![eof $gtf]} return
4169 close $gtf
4170 unset treepending
4171 if {$cmitmode ne "tree"} {
4172 if {![info exists diffmergeid]} {
4173 gettreediffs $diffids
4174 }
4175 } elseif {$id ne $diffids} {
4176 gettree $diffids
4177 } else {
4178 setfilelist $id
4179 }
4180}
4181
4182proc showfile {f} {
4183 global treefilelist treeidlist diffids
4184 global ctext commentend
4185
4186 set i [lsearch -exact $treefilelist($diffids) $f]
4187 if {$i < 0} {
4188 puts "oops, $f not in list for id $diffids"
4189 return
4190 }
4191 set blob [lindex $treeidlist($diffids) $i]
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004192 if {[catch {set bf [open [concat | git cat-file blob $blob] r]} err]} {
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004193 puts "oops, error reading blob $blob: $err"
4194 return
4195 }
4196 fconfigure $bf -blocking 0
4197 fileevent $bf readable [list getblobline $bf $diffids]
4198 $ctext config -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004199 clear_ctext $commentend
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004200 $ctext insert end "\n"
4201 $ctext insert end "$f\n" filesep
4202 $ctext config -state disabled
4203 $ctext yview $commentend
4204}
4205
4206proc getblobline {bf id} {
4207 global diffids cmitmode ctext
4208
4209 if {$id ne $diffids || $cmitmode ne "tree"} {
4210 catch {close $bf}
4211 return
4212 }
4213 $ctext config -state normal
4214 while {[gets $bf line] >= 0} {
4215 $ctext insert end "$line\n"
4216 }
4217 if {[eof $bf]} {
4218 # delete last newline
4219 $ctext delete "end - 2c" "end - 1c"
4220 close $bf
4221 }
4222 $ctext config -state disabled
4223}
4224
Paul Mackerras79b2c752006-04-02 20:47:40 +10004225proc mergediff {id l} {
4226 global diffmergeid diffopts mdifffd
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004227 global diffids
Paul Mackerras79b2c752006-04-02 20:47:40 +10004228 global parentlist
Paul Mackerrase2ed4322005-07-17 03:39:44 -04004229
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004230 set diffmergeid $id
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004231 set diffids $id
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004232 # this doesn't seem to actually affect anything...
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004233 set env(GIT_DIFF_OPTS) $diffopts
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004234 set cmd [concat | git diff-tree --no-commit-id --cc $id]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004235 if {[catch {set mdf [open $cmd r]} err]} {
4236 error_popup "Error getting merge diffs: $err"
4237 return
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004238 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004239 fconfigure $mdf -blocking 0
4240 set mdifffd($id) $mdf
Paul Mackerras79b2c752006-04-02 20:47:40 +10004241 set np [llength [lindex $parentlist $l]]
4242 fileevent $mdf readable [list getmergediffline $mdf $id $np]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004243 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004244}
4245
Paul Mackerras79b2c752006-04-02 20:47:40 +10004246proc getmergediffline {mdf id np} {
4247 global diffmergeid ctext cflist nextupdate mergemax
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004248 global difffilestart mdifffd
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004249
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004250 set n [gets $mdf line]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004251 if {$n < 0} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004252 if {[eof $mdf]} {
4253 close $mdf
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004254 }
4255 return
4256 }
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004257 if {![info exists diffmergeid] || $id != $diffmergeid
4258 || $mdf != $mdifffd($id)} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004259 return
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004260 }
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004261 $ctext conf -state normal
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004262 if {[regexp {^diff --cc (.*)} $line match fname]} {
4263 # start of a new file
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004264 $ctext insert end "\n"
4265 set here [$ctext index "end - 1c"]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004266 lappend difffilestart $here
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004267 add_flist [list $fname]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004268 set l [expr {(78 - [string length $fname]) / 2}]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004269 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004270 $ctext insert end "$pad $fname $pad\n" filesep
4271 } elseif {[regexp {^@@} $line]} {
4272 $ctext insert end "$line\n" hunksep
4273 } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
4274 # do nothing
4275 } else {
4276 # parse the prefix - one ' ', '-' or '+' for each parent
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004277 set spaces {}
4278 set minuses {}
4279 set pluses {}
4280 set isbad 0
4281 for {set j 0} {$j < $np} {incr j} {
4282 set c [string range $line $j $j]
4283 if {$c == " "} {
4284 lappend spaces $j
4285 } elseif {$c == "-"} {
4286 lappend minuses $j
4287 } elseif {$c == "+"} {
4288 lappend pluses $j
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004289 } else {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004290 set isbad 1
4291 break
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004292 }
4293 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004294 set tags {}
4295 set num {}
4296 if {!$isbad && $minuses ne {} && $pluses eq {}} {
4297 # line doesn't appear in result, parents in $minuses have the line
4298 set num [lindex $minuses 0]
4299 } elseif {!$isbad && $pluses ne {} && $minuses eq {}} {
4300 # line appears in result, parents in $pluses don't have the line
4301 lappend tags mresult
4302 set num [lindex $spaces 0]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004303 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004304 if {$num ne {}} {
4305 if {$num >= $mergemax} {
4306 set num "max"
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004307 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004308 lappend tags m$num
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004309 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004310 $ctext insert end "$line\n" $tags
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05004311 }
4312 $ctext conf -state disabled
Paul Mackerrasb77b0272006-02-07 09:13:52 +11004313 if {[clock clicks -milliseconds] >= $nextupdate} {
4314 incr nextupdate 100
4315 fileevent $mdf readable {}
4316 update
Paul Mackerrasc5a4c4d2006-04-06 10:20:03 +10004317 fileevent $mdf readable [list getmergediffline $mdf $id $np]
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05004318 }
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05004319}
4320
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004321proc startdiff {ids} {
4322 global treediffs diffids treepending diffmergeid
4323
4324 set diffids $ids
4325 catch {unset diffmergeid}
4326 if {![info exists treediffs($ids)]} {
4327 if {![info exists treepending]} {
4328 gettreediffs $ids
4329 }
4330 } else {
4331 addtocflist $ids
4332 }
4333}
4334
4335proc addtocflist {ids} {
4336 global treediffs cflist
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004337 add_flist $treediffs($ids)
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004338 getblobdiffs $ids
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004339}
4340
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004341proc gettreediffs {ids} {
Paul Mackerras79b2c752006-04-02 20:47:40 +10004342 global treediff treepending
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004343 set treepending $ids
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004344 set treediff {}
Paul Mackerras418c4c72006-02-07 09:10:18 +11004345 if {[catch \
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004346 {set gdtf [open [concat | git diff-tree --no-commit-id -r $ids] r]} \
Paul Mackerras418c4c72006-02-07 09:10:18 +11004347 ]} return
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004348 fconfigure $gdtf -blocking 0
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004349 fileevent $gdtf readable [list gettreediffline $gdtf $ids]
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004350}
4351
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004352proc gettreediffline {gdtf ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004353 global treediff treediffs treepending diffids diffmergeid
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004354 global cmitmode
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004355
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004356 set n [gets $gdtf line]
4357 if {$n < 0} {
4358 if {![eof $gdtf]} return
4359 close $gdtf
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004360 set treediffs($ids) $treediff
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004361 unset treepending
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10004362 if {$cmitmode eq "tree"} {
4363 gettree $diffids
4364 } elseif {$ids != $diffids} {
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004365 if {![info exists diffmergeid]} {
4366 gettreediffs $diffids
Paul Mackerrasb74fd572005-07-16 07:46:13 -04004367 }
Paul Mackerras7a1d9d12006-03-22 10:21:45 +11004368 } else {
4369 addtocflist $ids
Paul Mackerrasb74fd572005-07-16 07:46:13 -04004370 }
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004371 return
4372 }
Paul Mackerrasd4e95cb2005-06-01 00:02:13 +00004373 set file [lindex $line 5]
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004374 lappend treediff $file
Paul Mackerrasd2610d12005-05-11 00:45:38 +00004375}
4376
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004377proc getblobdiffs {ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004378 global diffopts blobdifffd diffids env curdifftag curtagstart
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004379 global nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004380
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004381 set env(GIT_DIFF_OPTS) $diffopts
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03004382 set cmd [concat | git diff-tree --no-commit-id -r -p -C $ids]
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004383 if {[catch {set bdf [open $cmd r]} err]} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004384 puts "error getting diffs: $err"
4385 return
4386 }
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004387 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004388 fconfigure $bdf -blocking 0
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004389 set blobdifffd($ids) $bdf
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004390 set curdifftag Comments
4391 set curtagstart 0.0
Paul Mackerras3c461ff2005-07-20 09:13:46 -04004392 fileevent $bdf readable [list getblobdiffline $bdf $diffids]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004393 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004394}
4395
Paul Mackerras89b11d32006-05-02 19:55:31 +10004396proc setinlist {var i val} {
4397 global $var
4398
4399 while {[llength [set $var]] < $i} {
4400 lappend $var {}
4401 }
4402 if {[llength [set $var]] == $i} {
4403 lappend $var $val
4404 } else {
4405 lset $var $i $val
4406 }
4407}
4408
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004409proc getblobdiffline {bdf ids} {
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004410 global diffids blobdifffd ctext curdifftag curtagstart
Paul Mackerras7eab2932005-07-20 12:25:54 -04004411 global diffnexthead diffnextnote difffilestart
4412 global nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004413
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004414 set n [gets $bdf line]
4415 if {$n < 0} {
4416 if {[eof $bdf]} {
4417 close $bdf
Paul Mackerrase2ed4322005-07-17 03:39:44 -04004418 if {$ids == $diffids && $bdf == $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004419 $ctext tag add $curdifftag $curtagstart end
4420 }
4421 }
4422 return
4423 }
Paul Mackerrase2ed4322005-07-17 03:39:44 -04004424 if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004425 return
4426 }
4427 $ctext conf -state normal
Paul Mackerras7eab2932005-07-20 12:25:54 -04004428 if {[regexp {^diff --git a/(.*) b/(.*)} $line match fname newname]} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004429 # start of a new file
4430 $ctext insert end "\n"
4431 $ctext tag add $curdifftag $curtagstart end
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004432 set here [$ctext index "end - 1c"]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004433 set curtagstart $here
4434 set header $newname
Paul Mackerras89b11d32006-05-02 19:55:31 +10004435 set i [lsearch -exact $treediffs($ids) $fname]
4436 if {$i >= 0} {
4437 setinlist difffilestart $i $here
4438 }
4439 if {$newname ne $fname} {
4440 set i [lsearch -exact $treediffs($ids) $newname]
4441 if {$i >= 0} {
4442 setinlist difffilestart $i $here
4443 }
Paul Mackerras7eab2932005-07-20 12:25:54 -04004444 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004445 set curdifftag "f:$fname"
4446 $ctext tag delete $curdifftag
Paul Mackerras58422152005-05-19 10:56:42 +00004447 set l [expr {(78 - [string length $header]) / 2}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004448 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerras58422152005-05-19 10:56:42 +00004449 $ctext insert end "$pad $header $pad\n" filesep
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004450 set diffinhdr 1
Paul Mackerrasb06bc2a2006-03-08 09:15:32 +11004451 } elseif {$diffinhdr && [string compare -length 3 $line "---"] == 0} {
4452 # do nothing
4453 } elseif {$diffinhdr && [string compare -length 3 $line "+++"] == 0} {
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004454 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004455 } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
4456 $line match f1l f1c f2l f2c rest]} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11004457 $ctext insert end "$line\n" hunksep
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004458 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004459 } else {
4460 set x [string range $line 0 0]
4461 if {$x == "-" || $x == "+"} {
4462 set tag [expr {$x == "+"}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004463 $ctext insert end "$line\n" d$tag
4464 } elseif {$x == " "} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004465 $ctext insert end "$line\n"
Paul Mackerras4f2c2642005-07-17 11:11:44 -04004466 } elseif {$diffinhdr || $x == "\\"} {
Paul Mackerras58422152005-05-19 10:56:42 +00004467 # e.g. "\ No newline at end of file"
4468 $ctext insert end "$line\n" filesep
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004469 } else {
4470 # Something else we don't recognize
4471 if {$curdifftag != "Comments"} {
4472 $ctext insert end "\n"
4473 $ctext tag add $curdifftag $curtagstart end
4474 set curtagstart [$ctext index "end - 1c"]
4475 set curdifftag Comments
4476 }
4477 $ctext insert end "$line\n" filesep
4478 }
4479 }
4480 $ctext conf -state disabled
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004481 if {[clock clicks -milliseconds] >= $nextupdate} {
4482 incr nextupdate 100
4483 fileevent $bdf readable {}
4484 update
4485 fileevent $bdf readable "getblobdiffline $bdf {$ids}"
4486 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00004487}
4488
OGAWA Hirofumi67c22872006-09-27 12:32:19 +09004489proc prevfile {} {
4490 global difffilestart ctext
4491 set prev [lindex $difffilestart 0]
4492 set here [$ctext index @0,0]
4493 foreach loc $difffilestart {
4494 if {[$ctext compare $loc >= $here]} {
4495 $ctext yview $prev
4496 return
4497 }
4498 set prev $loc
4499 }
4500 $ctext yview $prev
4501}
4502
Paul Mackerras39ad8572005-05-19 12:35:53 +00004503proc nextfile {} {
4504 global difffilestart ctext
4505 set here [$ctext index @0,0]
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004506 foreach loc $difffilestart {
4507 if {[$ctext compare $loc > $here]} {
4508 $ctext yview $loc
OGAWA Hirofumi67c22872006-09-27 12:32:19 +09004509 return
Paul Mackerras39ad8572005-05-19 12:35:53 +00004510 }
4511 }
Paul Mackerras1db95b02005-05-09 04:08:39 +00004512}
4513
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004514proc clear_ctext {{first 1.0}} {
4515 global ctext smarktop smarkbot
4516
Paul Mackerras1902c272006-05-25 21:25:13 +10004517 set l [lindex [split $first .] 0]
4518 if {![info exists smarktop] || [$ctext compare $first < $smarktop.0]} {
4519 set smarktop $l
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004520 }
Paul Mackerras1902c272006-05-25 21:25:13 +10004521 if {![info exists smarkbot] || [$ctext compare $first < $smarkbot.0]} {
4522 set smarkbot $l
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004523 }
4524 $ctext delete $first end
4525}
4526
4527proc incrsearch {name ix op} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004528 global ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004529
4530 $ctext tag remove found 1.0 end
Paul Mackerras1902c272006-05-25 21:25:13 +10004531 if {[catch {$ctext index anchor}]} {
4532 # no anchor set, use start of selection, or of visible area
4533 set sel [$ctext tag ranges sel]
4534 if {$sel ne {}} {
4535 $ctext mark set anchor [lindex $sel 0]
4536 } elseif {$searchdirn eq "-forwards"} {
4537 $ctext mark set anchor @0,0
4538 } else {
4539 $ctext mark set anchor @0,[winfo height $ctext]
4540 }
4541 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004542 if {$searchstring ne {}} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004543 set here [$ctext search $searchdirn -- $searchstring anchor]
4544 if {$here ne {}} {
4545 $ctext see $here
4546 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004547 searchmarkvisible 1
4548 }
4549}
4550
4551proc dosearch {} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004552 global sstring ctext searchstring searchdirn
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004553
4554 focus $sstring
4555 $sstring icursor end
Paul Mackerras1902c272006-05-25 21:25:13 +10004556 set searchdirn -forwards
4557 if {$searchstring ne {}} {
4558 set sel [$ctext tag ranges sel]
4559 if {$sel ne {}} {
4560 set start "[lindex $sel 0] + 1c"
4561 } elseif {[catch {set start [$ctext index anchor]}]} {
4562 set start "@0,0"
4563 }
4564 set match [$ctext search -count mlen -- $searchstring $start]
4565 $ctext tag remove sel 1.0 end
4566 if {$match eq {}} {
4567 bell
4568 return
4569 }
4570 $ctext see $match
4571 set mend "$match + $mlen c"
4572 $ctext tag add sel $match $mend
4573 $ctext mark unset anchor
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004574 }
Paul Mackerras1902c272006-05-25 21:25:13 +10004575}
4576
4577proc dosearchback {} {
4578 global sstring ctext searchstring searchdirn
4579
4580 focus $sstring
4581 $sstring icursor end
4582 set searchdirn -backwards
4583 if {$searchstring ne {}} {
4584 set sel [$ctext tag ranges sel]
4585 if {$sel ne {}} {
4586 set start [lindex $sel 0]
4587 } elseif {[catch {set start [$ctext index anchor]}]} {
4588 set start @0,[winfo height $ctext]
4589 }
4590 set match [$ctext search -backwards -count ml -- $searchstring $start]
4591 $ctext tag remove sel 1.0 end
4592 if {$match eq {}} {
4593 bell
4594 return
4595 }
4596 $ctext see $match
4597 set mend "$match + $ml c"
4598 $ctext tag add sel $match $mend
4599 $ctext mark unset anchor
4600 }
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004601}
4602
4603proc searchmark {first last} {
4604 global ctext searchstring
4605
4606 set mend $first.0
4607 while {1} {
4608 set match [$ctext search -count mlen -- $searchstring $mend $last.end]
4609 if {$match eq {}} break
4610 set mend "$match + $mlen c"
4611 $ctext tag add found $match $mend
4612 }
4613}
4614
4615proc searchmarkvisible {doall} {
4616 global ctext smarktop smarkbot
4617
4618 set topline [lindex [split [$ctext index @0,0] .] 0]
4619 set botline [lindex [split [$ctext index @0,[winfo height $ctext]] .] 0]
4620 if {$doall || $botline < $smarktop || $topline > $smarkbot} {
4621 # no overlap with previous
4622 searchmark $topline $botline
4623 set smarktop $topline
4624 set smarkbot $botline
4625 } else {
4626 if {$topline < $smarktop} {
4627 searchmark $topline [expr {$smarktop-1}]
4628 set smarktop $topline
4629 }
4630 if {$botline > $smarkbot} {
4631 searchmark [expr {$smarkbot+1}] $botline
4632 set smarkbot $botline
4633 }
4634 }
4635}
4636
4637proc scrolltext {f0 f1} {
Paul Mackerras1902c272006-05-25 21:25:13 +10004638 global searchstring
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004639
Junio C Hamanoe9937d22007-02-01 08:46:38 -05004640 .bleft.sb set $f0 $f1
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004641 if {$searchstring ne {}} {
4642 searchmarkvisible 0
4643 }
4644}
4645
Paul Mackerras1d10f362005-05-15 12:55:47 +00004646proc setcoords {} {
4647 global linespc charspc canvx0 canvy0 mainfont
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10004648 global xspc1 xspc2 lthickness
Paul Mackerras8d858d12005-08-05 09:52:16 +10004649
Paul Mackerras1d10f362005-05-15 12:55:47 +00004650 set linespc [font metrics $mainfont -linespace]
4651 set charspc [font measure $mainfont "m"]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004652 set canvy0 [expr {int(3 + 0.5 * $linespc)}]
4653 set canvx0 [expr {int(3 + 0.5 * $linespc)}]
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10004654 set lthickness [expr {int($linespc / 9) + 1}]
Paul Mackerras8d858d12005-08-05 09:52:16 +10004655 set xspc1(0) $linespc
4656 set xspc2 $linespc
Paul Mackerras9a40c502005-05-12 23:46:16 +00004657}
Paul Mackerras1db95b02005-05-09 04:08:39 +00004658
Paul Mackerras1d10f362005-05-15 12:55:47 +00004659proc redisplay {} {
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11004660 global canv
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004661 global selectedline
4662
4663 set ymax [lindex [$canv cget -scrollregion] 3]
4664 if {$ymax eq {} || $ymax == 0} return
4665 set span [$canv yview]
4666 clear_display
Paul Mackerrasbe0cd092006-03-31 09:55:11 +11004667 setcanvscroll
Paul Mackerras9f1afe02006-02-19 22:44:47 +11004668 allcanvs yview moveto [lindex $span 0]
4669 drawvisible
4670 if {[info exists selectedline]} {
4671 selectline $selectedline 0
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10004672 allcanvs yview moveto [lindex $span 0]
Paul Mackerras1db95b02005-05-09 04:08:39 +00004673 }
4674}
Paul Mackerras1d10f362005-05-15 12:55:47 +00004675
4676proc incrfont {inc} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004677 global mainfont textfont ctext canv phase
Paul Mackerrascfb45632005-05-31 12:14:42 +00004678 global stopped entries
Paul Mackerras1d10f362005-05-15 12:55:47 +00004679 unmarkmatches
4680 set mainfont [lreplace $mainfont 1 1 [expr {[lindex $mainfont 1] + $inc}]]
Paul Mackerras1d10f362005-05-15 12:55:47 +00004681 set textfont [lreplace $textfont 1 1 [expr {[lindex $textfont 1] + $inc}]]
4682 setcoords
4683 $ctext conf -font $textfont
4684 $ctext tag conf filesep -font [concat $textfont bold]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004685 foreach e $entries {
4686 $e conf -font $mainfont
4687 }
Paul Mackerras22626ef2006-04-17 09:56:02 +10004688 if {$phase eq "getcommits"} {
Paul Mackerras1d10f362005-05-15 12:55:47 +00004689 $canv itemconf textitems -font $mainfont
4690 }
4691 redisplay
Paul Mackerras1db95b02005-05-09 04:08:39 +00004692}
Paul Mackerras1d10f362005-05-15 12:55:47 +00004693
Paul Mackerrasee3dc722005-06-25 16:37:13 +10004694proc clearsha1 {} {
4695 global sha1entry sha1string
4696 if {[string length $sha1string] == 40} {
4697 $sha1entry delete 0 end
4698 }
4699}
4700
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004701proc sha1change {n1 n2 op} {
4702 global sha1string currentid sha1but
4703 if {$sha1string == {}
4704 || ([info exists currentid] && $sha1string == $currentid)} {
4705 set state disabled
4706 } else {
4707 set state normal
4708 }
4709 if {[$sha1but cget -state] == $state} return
4710 if {$state == "normal"} {
4711 $sha1but conf -state normal -relief raised -text "Goto: "
4712 } else {
4713 $sha1but conf -state disabled -relief flat -text "SHA1 ID: "
4714 }
4715}
4716
4717proc gotocommit {} {
Stephen Rothwelle1007122006-03-30 16:13:12 +11004718 global sha1string currentid commitrow tagids headids
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004719 global displayorder numcommits curview
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004720
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004721 if {$sha1string == {}
4722 || ([info exists currentid] && $sha1string == $currentid)} return
4723 if {[info exists tagids($sha1string)]} {
4724 set id $tagids($sha1string)
Stephen Rothwelle1007122006-03-30 16:13:12 +11004725 } elseif {[info exists headids($sha1string)]} {
4726 set id $headids($sha1string)
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004727 } else {
4728 set id [string tolower $sha1string]
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004729 if {[regexp {^[0-9a-f]{4,39}$} $id]} {
4730 set matches {}
Paul Mackerras8ed16482006-03-02 22:56:44 +11004731 foreach i $displayorder {
4732 if {[string match $id* $i]} {
4733 lappend matches $i
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004734 }
4735 }
4736 if {$matches ne {}} {
4737 if {[llength $matches] > 1} {
4738 error_popup "Short SHA1 id $id is ambiguous"
4739 return
4740 }
4741 set id [lindex $matches 0]
4742 }
4743 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004744 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004745 if {[info exists commitrow($curview,$id)]} {
4746 selectline $commitrow($curview,$id) 1
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004747 return
4748 }
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04004749 if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004750 set type "SHA1 id"
4751 } else {
Stephen Rothwelle1007122006-03-30 16:13:12 +11004752 set type "Tag/Head"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00004753 }
4754 error_popup "$type $sha1string is not known"
4755}
4756
Paul Mackerras84ba7342005-06-17 00:12:26 +00004757proc lineenter {x y id} {
4758 global hoverx hovery hoverid hovertimer
4759 global commitinfo canv
4760
Paul Mackerras8ed16482006-03-02 22:56:44 +11004761 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerras84ba7342005-06-17 00:12:26 +00004762 set hoverx $x
4763 set hovery $y
4764 set hoverid $id
4765 if {[info exists hovertimer]} {
4766 after cancel $hovertimer
4767 }
4768 set hovertimer [after 500 linehover]
4769 $canv delete hover
4770}
4771
4772proc linemotion {x y id} {
4773 global hoverx hovery hoverid hovertimer
4774
4775 if {[info exists hoverid] && $id == $hoverid} {
4776 set hoverx $x
4777 set hovery $y
4778 if {[info exists hovertimer]} {
4779 after cancel $hovertimer
4780 }
4781 set hovertimer [after 500 linehover]
4782 }
4783}
4784
4785proc lineleave {id} {
4786 global hoverid hovertimer canv
4787
4788 if {[info exists hoverid] && $id == $hoverid} {
4789 $canv delete hover
4790 if {[info exists hovertimer]} {
4791 after cancel $hovertimer
4792 unset hovertimer
4793 }
4794 unset hoverid
4795 }
4796}
4797
4798proc linehover {} {
4799 global hoverx hovery hoverid hovertimer
4800 global canv linespc lthickness
4801 global commitinfo mainfont
4802
4803 set text [lindex $commitinfo($hoverid) 0]
4804 set ymax [lindex [$canv cget -scrollregion] 3]
4805 if {$ymax == {}} return
4806 set yfrac [lindex [$canv yview] 0]
4807 set x [expr {$hoverx + 2 * $linespc}]
4808 set y [expr {$hovery + $yfrac * $ymax - $linespc / 2}]
4809 set x0 [expr {$x - 2 * $lthickness}]
4810 set y0 [expr {$y - 2 * $lthickness}]
4811 set x1 [expr {$x + [font measure $mainfont $text] + 2 * $lthickness}]
4812 set y1 [expr {$y + $linespc + 2 * $lthickness}]
4813 set t [$canv create rectangle $x0 $y0 $x1 $y1 \
4814 -fill \#ffff80 -outline black -width 1 -tags hover]
4815 $canv raise $t
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10004816 set t [$canv create text $x $y -anchor nw -text $text -tags hover \
4817 -font $mainfont]
Paul Mackerras84ba7342005-06-17 00:12:26 +00004818 $canv raise $t
4819}
4820
Paul Mackerras9843c302005-08-30 10:57:11 +10004821proc clickisonarrow {id y} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004822 global lthickness
Paul Mackerras9843c302005-08-30 10:57:11 +10004823
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004824 set ranges [rowranges $id]
Paul Mackerras9843c302005-08-30 10:57:11 +10004825 set thresh [expr {2 * $lthickness + 6}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004826 set n [expr {[llength $ranges] - 1}]
Paul Mackerrasf6342482006-02-28 10:02:03 +11004827 for {set i 1} {$i < $n} {incr i} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004828 set row [lindex $ranges $i]
Paul Mackerrasf6342482006-02-28 10:02:03 +11004829 if {abs([yc $row] - $y) < $thresh} {
4830 return $i
Paul Mackerras9843c302005-08-30 10:57:11 +10004831 }
4832 }
4833 return {}
4834}
4835
Paul Mackerrasf6342482006-02-28 10:02:03 +11004836proc arrowjump {id n y} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004837 global canv
Paul Mackerras9843c302005-08-30 10:57:11 +10004838
Paul Mackerrasf6342482006-02-28 10:02:03 +11004839 # 1 <-> 2, 3 <-> 4, etc...
4840 set n [expr {(($n - 1) ^ 1) + 1}]
Paul Mackerras50b44ec2006-04-04 10:16:22 +10004841 set row [lindex [rowranges $id] $n]
Paul Mackerrasf6342482006-02-28 10:02:03 +11004842 set yt [yc $row]
Paul Mackerras9843c302005-08-30 10:57:11 +10004843 set ymax [lindex [$canv cget -scrollregion] 3]
4844 if {$ymax eq {} || $ymax <= 0} return
4845 set view [$canv yview]
4846 set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
4847 set yfrac [expr {$yt / $ymax - $yspan / 2}]
4848 if {$yfrac < 0} {
4849 set yfrac 0
4850 }
Paul Mackerrasf6342482006-02-28 10:02:03 +11004851 allcanvs yview moveto $yfrac
Paul Mackerras9843c302005-08-30 10:57:11 +10004852}
4853
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004854proc lineclick {x y id isnew} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004855 global ctext commitinfo children canv thickerline curview
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004856
Paul Mackerras8ed16482006-03-02 22:56:44 +11004857 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004858 unmarkmatches
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004859 unselectline
Paul Mackerras9843c302005-08-30 10:57:11 +10004860 normalline
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004861 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10004862 # draw this line thicker than normal
Paul Mackerras9843c302005-08-30 10:57:11 +10004863 set thickerline $id
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004864 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10004865 if {$isnew} {
4866 set ymax [lindex [$canv cget -scrollregion] 3]
4867 if {$ymax eq {}} return
4868 set yfrac [lindex [$canv yview] 0]
4869 set y [expr {$y + $yfrac * $ymax}]
4870 }
4871 set dirn [clickisonarrow $id $y]
4872 if {$dirn ne {}} {
4873 arrowjump $id $dirn $y
4874 return
4875 }
4876
4877 if {$isnew} {
4878 addtohistory [list lineclick $x $y $id 0]
4879 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004880 # fill the details pane with info about this line
4881 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004882 clear_ctext
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004883 $ctext tag conf link -foreground blue -underline 1
4884 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
4885 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
4886 $ctext insert end "Parent:\t"
4887 $ctext insert end $id [list link link0]
4888 $ctext tag bind link0 <1> [list selbyid $id]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004889 set info $commitinfo($id)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004890 $ctext insert end "\n\t[lindex $info 0]\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004891 $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
Paul Mackerras232475d2005-11-15 10:34:03 +11004892 set date [formatdate [lindex $info 2]]
4893 $ctext insert end "\tDate:\t$date\n"
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004894 set kids $children($curview,$id)
Paul Mackerras79b2c752006-04-02 20:47:40 +10004895 if {$kids ne {}} {
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004896 $ctext insert end "\nChildren:"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004897 set i 0
Paul Mackerras79b2c752006-04-02 20:47:40 +10004898 foreach child $kids {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004899 incr i
Paul Mackerras8ed16482006-03-02 22:56:44 +11004900 if {![info exists commitinfo($child)] && ![getcommit $child]} continue
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004901 set info $commitinfo($child)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004902 $ctext insert end "\n\t"
4903 $ctext insert end $child [list link link$i]
4904 $ctext tag bind link$i <1> [list selbyid $child]
4905 $ctext insert end "\n\t[lindex $info 0]"
4906 $ctext insert end "\n\tAuthor:\t[lindex $info 1]"
Paul Mackerras232475d2005-11-15 10:34:03 +11004907 set date [formatdate [lindex $info 2]]
4908 $ctext insert end "\n\tDate:\t$date\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004909 }
4910 }
4911 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004912 init_flist {}
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004913}
4914
Paul Mackerras9843c302005-08-30 10:57:11 +10004915proc normalline {} {
4916 global thickerline
4917 if {[info exists thickerline]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004918 set id $thickerline
Paul Mackerras9843c302005-08-30 10:57:11 +10004919 unset thickerline
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11004920 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10004921 }
4922}
4923
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004924proc selbyid {id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004925 global commitrow curview
4926 if {[info exists commitrow($curview,$id)]} {
4927 selectline $commitrow($curview,$id) 1
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004928 }
4929}
4930
4931proc mstime {} {
4932 global startmstime
4933 if {![info exists startmstime]} {
4934 set startmstime [clock clicks -milliseconds]
4935 }
4936 return [format "%.3f" [expr {([clock click -milliseconds] - $startmstime) / 1000.0}]]
4937}
4938
4939proc rowmenu {x y id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004940 global rowctxmenu commitrow selectedline rowmenuid curview
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004941
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10004942 if {![info exists selectedline]
4943 || $commitrow($curview,$id) eq $selectedline} {
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004944 set state disabled
4945 } else {
4946 set state normal
4947 }
Paul Mackerras3cd204e2006-11-23 21:06:16 +11004948 $rowctxmenu entryconfigure "Diff this*" -state $state
4949 $rowctxmenu entryconfigure "Diff selected*" -state $state
4950 $rowctxmenu entryconfigure "Make patch" -state $state
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004951 set rowmenuid $id
4952 tk_popup $rowctxmenu $x $y
4953}
4954
4955proc diffvssel {dirn} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004956 global rowmenuid selectedline displayorder
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004957
4958 if {![info exists selectedline]} return
4959 if {$dirn} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004960 set oldid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004961 set newid $rowmenuid
4962 } else {
4963 set oldid $rowmenuid
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11004964 set newid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004965 }
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004966 addtohistory [list doseldiff $oldid $newid]
4967 doseldiff $oldid $newid
4968}
4969
4970proc doseldiff {oldid newid} {
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004971 global ctext
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004972 global commitinfo
4973
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004974 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10004975 clear_ctext
Paul Mackerras7fcceed2006-04-27 19:21:49 +10004976 init_flist "Top"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004977 $ctext insert end "From "
4978 $ctext tag conf link -foreground blue -underline 1
4979 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
4980 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
4981 $ctext tag bind link0 <1> [list selbyid $oldid]
4982 $ctext insert end $oldid [list link link0]
4983 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004984 $ctext insert end [lindex $commitinfo($oldid) 0]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10004985 $ctext insert end "\n\nTo "
4986 $ctext tag bind link1 <1> [list selbyid $newid]
4987 $ctext insert end $newid [list link link1]
4988 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004989 $ctext insert end [lindex $commitinfo($newid) 0]
4990 $ctext insert end "\n"
4991 $ctext conf -state disabled
4992 $ctext tag delete Comments
4993 $ctext tag remove found 1.0 end
Paul Mackerrasd3272442005-11-28 20:41:56 +11004994 startdiff [list $oldid $newid]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10004995}
4996
Paul Mackerras74daedb2005-06-27 19:27:32 +10004997proc mkpatch {} {
4998 global rowmenuid currentid commitinfo patchtop patchnum
4999
5000 if {![info exists currentid]} return
5001 set oldid $currentid
5002 set oldhead [lindex $commitinfo($oldid) 0]
5003 set newid $rowmenuid
5004 set newhead [lindex $commitinfo($newid) 0]
5005 set top .patch
5006 set patchtop $top
5007 catch {destroy $top}
5008 toplevel $top
5009 label $top.title -text "Generate patch"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005010 grid $top.title - -pady 10
Paul Mackerras74daedb2005-06-27 19:27:32 +10005011 label $top.from -text "From:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005012 entry $top.fromsha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10005013 $top.fromsha1 insert 0 $oldid
5014 $top.fromsha1 conf -state readonly
5015 grid $top.from $top.fromsha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005016 entry $top.fromhead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10005017 $top.fromhead insert 0 $oldhead
5018 $top.fromhead conf -state readonly
5019 grid x $top.fromhead -sticky w
5020 label $top.to -text "To:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005021 entry $top.tosha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10005022 $top.tosha1 insert 0 $newid
5023 $top.tosha1 conf -state readonly
5024 grid $top.to $top.tosha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005025 entry $top.tohead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10005026 $top.tohead insert 0 $newhead
5027 $top.tohead conf -state readonly
5028 grid x $top.tohead -sticky w
5029 button $top.rev -text "Reverse" -command mkpatchrev -padx 5
5030 grid $top.rev x -pady 10
5031 label $top.flab -text "Output file:"
5032 entry $top.fname -width 60
5033 $top.fname insert 0 [file normalize "patch$patchnum.patch"]
5034 incr patchnum
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005035 grid $top.flab $top.fname -sticky w
Paul Mackerras74daedb2005-06-27 19:27:32 +10005036 frame $top.buts
5037 button $top.buts.gen -text "Generate" -command mkpatchgo
5038 button $top.buts.can -text "Cancel" -command mkpatchcan
5039 grid $top.buts.gen $top.buts.can
5040 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5041 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5042 grid $top.buts - -pady 10 -sticky ew
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005043 focus $top.fname
Paul Mackerras74daedb2005-06-27 19:27:32 +10005044}
5045
5046proc mkpatchrev {} {
5047 global patchtop
5048
5049 set oldid [$patchtop.fromsha1 get]
5050 set oldhead [$patchtop.fromhead get]
5051 set newid [$patchtop.tosha1 get]
5052 set newhead [$patchtop.tohead get]
5053 foreach e [list fromsha1 fromhead tosha1 tohead] \
5054 v [list $newid $newhead $oldid $oldhead] {
5055 $patchtop.$e conf -state normal
5056 $patchtop.$e delete 0 end
5057 $patchtop.$e insert 0 $v
5058 $patchtop.$e conf -state readonly
5059 }
5060}
5061
5062proc mkpatchgo {} {
5063 global patchtop
5064
5065 set oldid [$patchtop.fromsha1 get]
5066 set newid [$patchtop.tosha1 get]
5067 set fname [$patchtop.fname get]
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03005068 if {[catch {exec git diff-tree -p $oldid $newid >$fname &} err]} {
Paul Mackerras74daedb2005-06-27 19:27:32 +10005069 error_popup "Error creating patch: $err"
5070 }
5071 catch {destroy $patchtop}
5072 unset patchtop
5073}
5074
5075proc mkpatchcan {} {
5076 global patchtop
5077
5078 catch {destroy $patchtop}
5079 unset patchtop
5080}
5081
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005082proc mktag {} {
5083 global rowmenuid mktagtop commitinfo
5084
5085 set top .maketag
5086 set mktagtop $top
5087 catch {destroy $top}
5088 toplevel $top
5089 label $top.title -text "Create tag"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005090 grid $top.title - -pady 10
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005091 label $top.id -text "ID:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005092 entry $top.sha1 -width 40 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005093 $top.sha1 insert 0 $rowmenuid
5094 $top.sha1 conf -state readonly
5095 grid $top.id $top.sha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005096 entry $top.head -width 60 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005097 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
5098 $top.head conf -state readonly
5099 grid x $top.head -sticky w
5100 label $top.tlab -text "Tag name:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005101 entry $top.tag -width 60
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005102 grid $top.tlab $top.tag -sticky w
5103 frame $top.buts
5104 button $top.buts.gen -text "Create" -command mktaggo
5105 button $top.buts.can -text "Cancel" -command mktagcan
5106 grid $top.buts.gen $top.buts.can
5107 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5108 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5109 grid $top.buts - -pady 10 -sticky ew
5110 focus $top.tag
5111}
5112
5113proc domktag {} {
5114 global mktagtop env tagids idtags
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005115
5116 set id [$mktagtop.sha1 get]
5117 set tag [$mktagtop.tag get]
5118 if {$tag == {}} {
5119 error_popup "No tag name specified"
5120 return
5121 }
5122 if {[info exists tagids($tag)]} {
5123 error_popup "Tag \"$tag\" already exists"
5124 return
5125 }
5126 if {[catch {
Junio C Hamano73b6a6c2005-07-28 00:28:44 -07005127 set dir [gitdir]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005128 set fname [file join $dir "refs/tags" $tag]
5129 set f [open $fname w]
5130 puts $f $id
5131 close $f
5132 } err]} {
5133 error_popup "Error creating tag: $err"
5134 return
5135 }
5136
5137 set tagids($tag) $id
5138 lappend idtags($id) $tag
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005139 redrawtags $id
Paul Mackerrasceadfe92006-08-08 20:55:36 +10005140 addedtag $id
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005141}
5142
5143proc redrawtags {id} {
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005144 global canv linehtag commitrow idpos selectedline curview
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005145 global mainfont canvxmax
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005146
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005147 if {![info exists commitrow($curview,$id)]} return
5148 drawcmitrow $commitrow($curview,$id)
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005149 $canv delete tag.$id
5150 set xt [eval drawtags $id $idpos($id)]
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005151 $canv coords $linehtag($commitrow($curview,$id)) $xt [lindex $idpos($id) 2]
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005152 set text [$canv itemcget $linehtag($commitrow($curview,$id)) -text]
5153 set xr [expr {$xt + [font measure $mainfont $text]}]
5154 if {$xr > $canvxmax} {
5155 set canvxmax $xr
5156 setcanvscroll
5157 }
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10005158 if {[info exists selectedline]
5159 && $selectedline == $commitrow($curview,$id)} {
Paul Mackerrasd6982062005-08-06 22:06:06 +10005160 selectline $selectedline 0
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10005161 }
5162}
5163
5164proc mktagcan {} {
5165 global mktagtop
5166
5167 catch {destroy $mktagtop}
5168 unset mktagtop
5169}
5170
5171proc mktaggo {} {
5172 domktag
5173 mktagcan
5174}
5175
Paul Mackerras4a2139f2005-06-29 09:47:48 +10005176proc writecommit {} {
5177 global rowmenuid wrcomtop commitinfo wrcomcmd
5178
5179 set top .writecommit
5180 set wrcomtop $top
5181 catch {destroy $top}
5182 toplevel $top
5183 label $top.title -text "Write commit to file"
5184 grid $top.title - -pady 10
5185 label $top.id -text "ID:"
5186 entry $top.sha1 -width 40 -relief flat
5187 $top.sha1 insert 0 $rowmenuid
5188 $top.sha1 conf -state readonly
5189 grid $top.id $top.sha1 -sticky w
5190 entry $top.head -width 60 -relief flat
5191 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
5192 $top.head conf -state readonly
5193 grid x $top.head -sticky w
5194 label $top.clab -text "Command:"
5195 entry $top.cmd -width 60 -textvariable wrcomcmd
5196 grid $top.clab $top.cmd -sticky w -pady 10
5197 label $top.flab -text "Output file:"
5198 entry $top.fname -width 60
5199 $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"]
5200 grid $top.flab $top.fname -sticky w
5201 frame $top.buts
5202 button $top.buts.gen -text "Write" -command wrcomgo
5203 button $top.buts.can -text "Cancel" -command wrcomcan
5204 grid $top.buts.gen $top.buts.can
5205 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5206 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5207 grid $top.buts - -pady 10 -sticky ew
5208 focus $top.fname
5209}
5210
5211proc wrcomgo {} {
5212 global wrcomtop
5213
5214 set id [$wrcomtop.sha1 get]
5215 set cmd "echo $id | [$wrcomtop.cmd get]"
5216 set fname [$wrcomtop.fname get]
5217 if {[catch {exec sh -c $cmd >$fname &} err]} {
5218 error_popup "Error writing commit: $err"
5219 }
5220 catch {destroy $wrcomtop}
5221 unset wrcomtop
5222}
5223
5224proc wrcomcan {} {
5225 global wrcomtop
5226
5227 catch {destroy $wrcomtop}
5228 unset wrcomtop
5229}
5230
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005231proc mkbranch {} {
5232 global rowmenuid mkbrtop
5233
5234 set top .makebranch
5235 catch {destroy $top}
5236 toplevel $top
5237 label $top.title -text "Create new branch"
5238 grid $top.title - -pady 10
5239 label $top.id -text "ID:"
5240 entry $top.sha1 -width 40 -relief flat
5241 $top.sha1 insert 0 $rowmenuid
5242 $top.sha1 conf -state readonly
5243 grid $top.id $top.sha1 -sticky w
5244 label $top.nlab -text "Name:"
5245 entry $top.name -width 40
5246 grid $top.nlab $top.name -sticky w
5247 frame $top.buts
5248 button $top.buts.go -text "Create" -command [list mkbrgo $top]
5249 button $top.buts.can -text "Cancel" -command "catch {destroy $top}"
5250 grid $top.buts.go $top.buts.can
5251 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5252 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5253 grid $top.buts - -pady 10 -sticky ew
5254 focus $top.name
5255}
5256
5257proc mkbrgo {top} {
5258 global headids idheads
5259
5260 set name [$top.name get]
5261 set id [$top.sha1 get]
5262 if {$name eq {}} {
5263 error_popup "Please specify a name for the new branch"
5264 return
5265 }
5266 catch {destroy $top}
5267 nowbusy newbranch
5268 update
5269 if {[catch {
5270 exec git branch $name $id
5271 } err]} {
5272 notbusy newbranch
5273 error_popup $err
5274 } else {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005275 addedhead $id $name
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005276 # XXX should update list of heads displayed for selected commit
5277 notbusy newbranch
5278 redrawtags $id
5279 }
5280}
5281
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005282proc cherrypick {} {
5283 global rowmenuid curview commitrow
5284 global mainhead desc_heads anc_tags desc_tags allparents allchildren
5285
5286 if {[info exists desc_heads($rowmenuid)]
5287 && [lsearch -exact $desc_heads($rowmenuid) $mainhead] >= 0} {
5288 set ok [confirm_popup "Commit [string range $rowmenuid 0 7] is already\
5289 included in branch $mainhead -- really re-apply it?"]
5290 if {!$ok} return
5291 }
5292 nowbusy cherrypick
5293 update
5294 set oldhead [exec git rev-parse HEAD]
5295 # Unfortunately git-cherry-pick writes stuff to stderr even when
5296 # no error occurs, and exec takes that as an indication of error...
5297 if {[catch {exec sh -c "git cherry-pick -r $rowmenuid 2>&1"} err]} {
5298 notbusy cherrypick
5299 error_popup $err
5300 return
5301 }
5302 set newhead [exec git rev-parse HEAD]
5303 if {$newhead eq $oldhead} {
5304 notbusy cherrypick
5305 error_popup "No changes committed"
5306 return
5307 }
5308 set allparents($newhead) $oldhead
5309 lappend allchildren($oldhead) $newhead
5310 set desc_heads($newhead) $mainhead
5311 if {[info exists anc_tags($oldhead)]} {
5312 set anc_tags($newhead) $anc_tags($oldhead)
5313 }
5314 set desc_tags($newhead) {}
5315 if {[info exists commitrow($curview,$oldhead)]} {
5316 insertrow $commitrow($curview,$oldhead) $newhead
5317 if {$mainhead ne {}} {
5318 movedhead $newhead $mainhead
5319 }
5320 redrawtags $oldhead
5321 redrawtags $newhead
5322 }
5323 notbusy cherrypick
5324}
5325
Paul Mackerras10299152006-08-02 09:52:01 +10005326# context menu for a head
5327proc headmenu {x y id head} {
5328 global headmenuid headmenuhead headctxmenu
5329
5330 set headmenuid $id
5331 set headmenuhead $head
5332 tk_popup $headctxmenu $x $y
5333}
5334
5335proc cobranch {} {
5336 global headmenuid headmenuhead mainhead headids
5337
5338 # check the tree is clean first??
5339 set oldmainhead $mainhead
5340 nowbusy checkout
5341 update
5342 if {[catch {
5343 exec git checkout $headmenuhead
5344 } err]} {
5345 notbusy checkout
5346 error_popup $err
5347 } else {
5348 notbusy checkout
Paul Mackerras53cda8d2006-08-02 19:43:34 +10005349 set mainhead $headmenuhead
Paul Mackerras10299152006-08-02 09:52:01 +10005350 if {[info exists headids($oldmainhead)]} {
5351 redrawtags $headids($oldmainhead)
5352 }
5353 redrawtags $headmenuid
5354 }
5355}
5356
5357proc rmbranch {} {
5358 global desc_heads headmenuid headmenuhead mainhead
5359 global headids idheads
5360
5361 set head $headmenuhead
5362 set id $headmenuid
5363 if {$head eq $mainhead} {
5364 error_popup "Cannot delete the currently checked-out branch"
5365 return
5366 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005367 if {$desc_heads($id) eq $head} {
Paul Mackerras10299152006-08-02 09:52:01 +10005368 # the stuff on this branch isn't on any other branch
5369 if {![confirm_popup "The commits on branch $head aren't on any other\
5370 branch.\nReally delete branch $head?"]} return
5371 }
5372 nowbusy rmbranch
5373 update
5374 if {[catch {exec git branch -D $head} err]} {
5375 notbusy rmbranch
5376 error_popup $err
5377 return
5378 }
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005379 removedhead $id $head
Paul Mackerras10299152006-08-02 09:52:01 +10005380 redrawtags $id
5381 notbusy rmbranch
5382}
5383
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005384# Stuff for finding nearby tags
5385proc getallcommits {} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005386 global allcstart allcommits allcfd allids
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005387
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005388 set allids {}
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005389 set fd [open [concat | git rev-list --all --topo-order --parents] r]
Paul Mackerras2d71bcc2006-06-07 09:19:45 +10005390 set allcfd $fd
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005391 fconfigure $fd -blocking 0
5392 set allcommits "reading"
5393 nowbusy allcommits
5394 restartgetall $fd
5395}
5396
Paul Mackerras2d71bcc2006-06-07 09:19:45 +10005397proc discardallcommits {} {
5398 global allparents allchildren allcommits allcfd
5399 global desc_tags anc_tags alldtags tagisdesc allids desc_heads
5400
5401 if {![info exists allcommits]} return
5402 if {$allcommits eq "reading"} {
5403 catch {close $allcfd}
5404 }
5405 foreach v {allcommits allchildren allparents allids desc_tags anc_tags
5406 alldtags tagisdesc desc_heads} {
5407 catch {unset $v}
5408 }
5409}
5410
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005411proc restartgetall {fd} {
5412 global allcstart
5413
5414 fileevent $fd readable [list getallclines $fd]
5415 set allcstart [clock clicks -milliseconds]
5416}
5417
5418proc combine_dtags {l1 l2} {
5419 global tagisdesc notfirstd
5420
5421 set res [lsort -unique [concat $l1 $l2]]
5422 for {set i 0} {$i < [llength $res]} {incr i} {
5423 set x [lindex $res $i]
5424 for {set j [expr {$i+1}]} {$j < [llength $res]} {} {
5425 set y [lindex $res $j]
5426 if {[info exists tagisdesc($x,$y)]} {
5427 if {$tagisdesc($x,$y) > 0} {
5428 # x is a descendent of y, exclude x
5429 set res [lreplace $res $i $i]
5430 incr i -1
5431 break
5432 } else {
5433 # y is a descendent of x, exclude y
5434 set res [lreplace $res $j $j]
5435 }
5436 } else {
5437 # no relation, keep going
5438 incr j
5439 }
5440 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005441 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005442 return $res
5443}
5444
5445proc combine_atags {l1 l2} {
5446 global tagisdesc
5447
5448 set res [lsort -unique [concat $l1 $l2]]
5449 for {set i 0} {$i < [llength $res]} {incr i} {
5450 set x [lindex $res $i]
5451 for {set j [expr {$i+1}]} {$j < [llength $res]} {} {
5452 set y [lindex $res $j]
5453 if {[info exists tagisdesc($x,$y)]} {
5454 if {$tagisdesc($x,$y) < 0} {
5455 # x is an ancestor of y, exclude x
5456 set res [lreplace $res $i $i]
5457 incr i -1
5458 break
5459 } else {
5460 # y is an ancestor of x, exclude y
5461 set res [lreplace $res $j $j]
5462 }
5463 } else {
5464 # no relation, keep going
5465 incr j
5466 }
5467 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005468 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005469 return $res
5470}
5471
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005472proc forward_pass {id children} {
5473 global idtags desc_tags idheads desc_heads alldtags tagisdesc
5474
5475 set dtags {}
5476 set dheads {}
5477 foreach child $children {
5478 if {[info exists idtags($child)]} {
5479 set ctags [list $child]
5480 } else {
5481 set ctags $desc_tags($child)
5482 }
5483 if {$dtags eq {}} {
5484 set dtags $ctags
5485 } elseif {$ctags ne $dtags} {
5486 set dtags [combine_dtags $dtags $ctags]
5487 }
5488 set cheads $desc_heads($child)
5489 if {$dheads eq {}} {
5490 set dheads $cheads
5491 } elseif {$cheads ne $dheads} {
5492 set dheads [lsort -unique [concat $dheads $cheads]]
5493 }
5494 }
5495 set desc_tags($id) $dtags
5496 if {[info exists idtags($id)]} {
5497 set adt $dtags
5498 foreach tag $dtags {
5499 set adt [concat $adt $alldtags($tag)]
5500 }
5501 set adt [lsort -unique $adt]
5502 set alldtags($id) $adt
5503 foreach tag $adt {
5504 set tagisdesc($id,$tag) -1
5505 set tagisdesc($tag,$id) 1
5506 }
5507 }
5508 if {[info exists idheads($id)]} {
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005509 set dheads [concat $dheads $idheads($id)]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005510 }
5511 set desc_heads($id) $dheads
5512}
5513
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005514proc getallclines {fd} {
5515 global allparents allchildren allcommits allcstart
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005516 global desc_tags anc_tags idtags tagisdesc allids
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005517 global idheads travindex
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005518
5519 while {[gets $fd line] >= 0} {
5520 set id [lindex $line 0]
5521 lappend allids $id
5522 set olds [lrange $line 1 end]
5523 set allparents($id) $olds
5524 if {![info exists allchildren($id)]} {
5525 set allchildren($id) {}
5526 }
5527 foreach p $olds {
5528 lappend allchildren($p) $id
5529 }
5530 # compute nearest tagged descendents as we go
Paul Mackerrasef030b82006-06-04 11:50:38 +10005531 # also compute descendent heads
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005532 forward_pass $id $allchildren($id)
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005533 if {[clock clicks -milliseconds] - $allcstart >= 50} {
5534 fileevent $fd readable {}
5535 after idle restartgetall $fd
5536 return
5537 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005538 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005539 if {[eof $fd]} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005540 set travindex [llength $allids]
5541 set allcommits "traversing"
5542 after idle restartatags
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005543 if {[catch {close $fd} err]} {
5544 error_popup "Error reading full commit graph: $err.\n\
5545 Results may be incomplete."
5546 }
5547 }
5548}
5549
5550# walk backward through the tree and compute nearest tagged ancestors
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005551proc restartatags {} {
5552 global allids allparents idtags anc_tags travindex
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005553
5554 set t0 [clock clicks -milliseconds]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005555 set i $travindex
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005556 while {[incr i -1] >= 0} {
5557 set id [lindex $allids $i]
5558 set atags {}
5559 foreach p $allparents($id) {
5560 if {[info exists idtags($p)]} {
5561 set ptags [list $p]
5562 } else {
5563 set ptags $anc_tags($p)
5564 }
5565 if {$atags eq {}} {
5566 set atags $ptags
5567 } elseif {$ptags ne $atags} {
5568 set atags [combine_atags $atags $ptags]
5569 }
5570 }
5571 set anc_tags($id) $atags
5572 if {[clock clicks -milliseconds] - $t0 >= 50} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005573 set travindex $i
5574 after idle restartatags
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005575 return
5576 }
5577 }
5578 set allcommits "done"
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005579 set travindex 0
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005580 notbusy allcommits
5581 dispneartags
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005582}
5583
Paul Mackerrasceadfe92006-08-08 20:55:36 +10005584# update the desc_tags and anc_tags arrays for a new tag just added
5585proc addedtag {id} {
5586 global desc_tags anc_tags allparents allchildren allcommits
5587 global idtags tagisdesc alldtags
5588
5589 if {![info exists desc_tags($id)]} return
5590 set adt $desc_tags($id)
5591 foreach t $desc_tags($id) {
5592 set adt [concat $adt $alldtags($t)]
5593 }
5594 set adt [lsort -unique $adt]
5595 set alldtags($id) $adt
5596 foreach t $adt {
5597 set tagisdesc($id,$t) -1
5598 set tagisdesc($t,$id) 1
5599 }
5600 if {[info exists anc_tags($id)]} {
5601 set todo $anc_tags($id)
5602 while {$todo ne {}} {
5603 set do [lindex $todo 0]
5604 set todo [lrange $todo 1 end]
5605 if {[info exists tagisdesc($id,$do)]} continue
5606 set tagisdesc($do,$id) -1
5607 set tagisdesc($id,$do) 1
5608 if {[info exists anc_tags($do)]} {
5609 set todo [concat $todo $anc_tags($do)]
5610 }
5611 }
5612 }
5613
5614 set lastold $desc_tags($id)
5615 set lastnew [list $id]
5616 set nup 0
5617 set nch 0
5618 set todo $allparents($id)
5619 while {$todo ne {}} {
5620 set do [lindex $todo 0]
5621 set todo [lrange $todo 1 end]
5622 if {![info exists desc_tags($do)]} continue
5623 if {$desc_tags($do) ne $lastold} {
5624 set lastold $desc_tags($do)
5625 set lastnew [combine_dtags $lastold [list $id]]
5626 incr nch
5627 }
5628 if {$lastold eq $lastnew} continue
5629 set desc_tags($do) $lastnew
5630 incr nup
5631 if {![info exists idtags($do)]} {
5632 set todo [concat $todo $allparents($do)]
5633 }
5634 }
5635
5636 if {![info exists anc_tags($id)]} return
5637 set lastold $anc_tags($id)
5638 set lastnew [list $id]
5639 set nup 0
5640 set nch 0
5641 set todo $allchildren($id)
5642 while {$todo ne {}} {
5643 set do [lindex $todo 0]
5644 set todo [lrange $todo 1 end]
5645 if {![info exists anc_tags($do)]} continue
5646 if {$anc_tags($do) ne $lastold} {
5647 set lastold $anc_tags($do)
5648 set lastnew [combine_atags $lastold [list $id]]
5649 incr nch
5650 }
5651 if {$lastold eq $lastnew} continue
5652 set anc_tags($do) $lastnew
5653 incr nup
5654 if {![info exists idtags($do)]} {
5655 set todo [concat $todo $allchildren($do)]
5656 }
5657 }
5658}
5659
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005660# update the desc_heads array for a new head just added
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005661proc addedhead {hid head} {
5662 global desc_heads allparents headids idheads
5663
5664 set headids($head) $hid
5665 lappend idheads($hid) $head
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005666
5667 set todo [list $hid]
5668 while {$todo ne {}} {
5669 set do [lindex $todo 0]
5670 set todo [lrange $todo 1 end]
5671 if {![info exists desc_heads($do)] ||
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005672 [lsearch -exact $desc_heads($do) $head] >= 0} continue
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005673 set oldheads $desc_heads($do)
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005674 lappend desc_heads($do) $head
Paul Mackerrasd6ac1a82006-08-02 09:41:04 +10005675 set heads $desc_heads($do)
5676 while {1} {
5677 set p $allparents($do)
5678 if {[llength $p] != 1 || ![info exists desc_heads($p)] ||
5679 $desc_heads($p) ne $oldheads} break
5680 set do $p
5681 set desc_heads($do) $heads
5682 }
5683 set todo [concat $todo $p]
5684 }
5685}
5686
Paul Mackerras10299152006-08-02 09:52:01 +10005687# update the desc_heads array for a head just removed
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005688proc removedhead {hid head} {
5689 global desc_heads allparents headids idheads
5690
5691 unset headids($head)
5692 if {$idheads($hid) eq $head} {
5693 unset idheads($hid)
5694 } else {
5695 set i [lsearch -exact $idheads($hid) $head]
5696 if {$i >= 0} {
5697 set idheads($hid) [lreplace $idheads($hid) $i $i]
5698 }
5699 }
Paul Mackerras10299152006-08-02 09:52:01 +10005700
5701 set todo [list $hid]
5702 while {$todo ne {}} {
5703 set do [lindex $todo 0]
5704 set todo [lrange $todo 1 end]
5705 if {![info exists desc_heads($do)]} continue
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005706 set i [lsearch -exact $desc_heads($do) $head]
Paul Mackerras10299152006-08-02 09:52:01 +10005707 if {$i < 0} continue
5708 set oldheads $desc_heads($do)
5709 set heads [lreplace $desc_heads($do) $i $i]
5710 while {1} {
5711 set desc_heads($do) $heads
5712 set p $allparents($do)
5713 if {[llength $p] != 1 || ![info exists desc_heads($p)] ||
5714 $desc_heads($p) ne $oldheads} break
5715 set do $p
5716 }
5717 set todo [concat $todo $p]
5718 }
5719}
5720
Paul Mackerrasca6d8f52006-08-06 21:08:05 +10005721# update things for a head moved to a child of its previous location
5722proc movedhead {id name} {
5723 global headids idheads
5724
5725 set oldid $headids($name)
5726 set headids($name) $id
5727 if {$idheads($oldid) eq $name} {
5728 unset idheads($oldid)
5729 } else {
5730 set i [lsearch -exact $idheads($oldid) $name]
5731 if {$i >= 0} {
5732 set idheads($oldid) [lreplace $idheads($oldid) $i $i]
5733 }
5734 }
5735 lappend idheads($id) $name
5736}
5737
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005738proc changedrefs {} {
5739 global desc_heads desc_tags anc_tags allcommits allids
5740 global allchildren allparents idtags travindex
5741
5742 if {![info exists allcommits]} return
5743 catch {unset desc_heads}
5744 catch {unset desc_tags}
5745 catch {unset anc_tags}
5746 catch {unset alldtags}
5747 catch {unset tagisdesc}
5748 foreach id $allids {
5749 forward_pass $id $allchildren($id)
5750 }
5751 if {$allcommits ne "reading"} {
5752 set travindex [llength $allids]
5753 if {$allcommits ne "traversing"} {
5754 set allcommits "traversing"
5755 after idle restartatags
5756 }
5757 }
5758}
5759
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005760proc rereadrefs {} {
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005761 global idtags idheads idotherrefs mainhead
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005762
5763 set refids [concat [array names idtags] \
5764 [array names idheads] [array names idotherrefs]]
5765 foreach id $refids {
5766 if {![info exists ref($id)]} {
5767 set ref($id) [listrefs $id]
5768 }
5769 }
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005770 set oldmainhead $mainhead
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005771 readrefs
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005772 changedrefs
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005773 set refids [lsort -unique [concat $refids [array names idtags] \
5774 [array names idheads] [array names idotherrefs]]]
5775 foreach id $refids {
5776 set v [listrefs $id]
Paul Mackerrascec7bec2006-08-02 09:38:10 +10005777 if {![info exists ref($id)] || $ref($id) != $v ||
5778 ($id eq $oldmainhead && $id ne $mainhead) ||
5779 ($id eq $mainhead && $id ne $oldmainhead)} {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10005780 redrawtags $id
5781 }
5782 }
5783}
5784
Junio C Hamano2e1ded42006-06-11 09:50:47 -07005785proc listrefs {id} {
5786 global idtags idheads idotherrefs
5787
5788 set x {}
5789 if {[info exists idtags($id)]} {
5790 set x $idtags($id)
5791 }
5792 set y {}
5793 if {[info exists idheads($id)]} {
5794 set y $idheads($id)
5795 }
5796 set z {}
5797 if {[info exists idotherrefs($id)]} {
5798 set z $idotherrefs($id)
5799 }
5800 return [list $x $y $z]
5801}
5802
Paul Mackerras106288c2005-08-19 23:11:39 +10005803proc showtag {tag isnew} {
Paul Mackerras7fcceed2006-04-27 19:21:49 +10005804 global ctext tagcontents tagids linknum
Paul Mackerras106288c2005-08-19 23:11:39 +10005805
5806 if {$isnew} {
5807 addtohistory [list showtag $tag 0]
5808 }
5809 $ctext conf -state normal
Paul Mackerras3ea06f92006-05-24 10:16:03 +10005810 clear_ctext
Paul Mackerras106288c2005-08-19 23:11:39 +10005811 set linknum 0
5812 if {[info exists tagcontents($tag)]} {
5813 set text $tagcontents($tag)
5814 } else {
5815 set text "Tag: $tag\nId: $tagids($tag)"
5816 }
Sergey Vlasovf1b86292006-05-15 19:13:14 +04005817 appendwithlinks $text {}
Paul Mackerras106288c2005-08-19 23:11:39 +10005818 $ctext conf -state disabled
Paul Mackerras7fcceed2006-04-27 19:21:49 +10005819 init_flist {}
Paul Mackerras106288c2005-08-19 23:11:39 +10005820}
5821
Paul Mackerras1d10f362005-05-15 12:55:47 +00005822proc doquit {} {
5823 global stopped
5824 set stopped 100
Mark Levedahlb6047c52007-02-08 22:22:24 -05005825 savestuff .
Paul Mackerras1d10f362005-05-15 12:55:47 +00005826 destroy .
5827}
5828
Paul Mackerras712fcc02005-11-30 09:28:16 +11005829proc doprefs {} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10005830 global maxwidth maxgraphpct diffopts
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005831 global oldprefs prefstop showneartags
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005832 global bgcolor fgcolor ctext diffcolors
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04005833 global uifont
Paul Mackerras232475d2005-11-15 10:34:03 +11005834
Paul Mackerras712fcc02005-11-30 09:28:16 +11005835 set top .gitkprefs
5836 set prefstop $top
5837 if {[winfo exists $top]} {
5838 raise $top
5839 return
Paul Mackerras757f17b2005-11-21 09:56:07 +11005840 }
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005841 foreach v {maxwidth maxgraphpct diffopts showneartags} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11005842 set oldprefs($v) [set $v]
Paul Mackerras232475d2005-11-15 10:34:03 +11005843 }
Paul Mackerras712fcc02005-11-30 09:28:16 +11005844 toplevel $top
5845 wm title $top "Gitk preferences"
5846 label $top.ldisp -text "Commit list display options"
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04005847 $top.ldisp configure -font $uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +11005848 grid $top.ldisp - -sticky w -pady 10
5849 label $top.spacer -text " "
5850 label $top.maxwidthl -text "Maximum graph width (lines)" \
5851 -font optionfont
5852 spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
5853 grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
5854 label $top.maxpctl -text "Maximum graph width (% of pane)" \
5855 -font optionfont
5856 spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
5857 grid x $top.maxpctl $top.maxpct -sticky w
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005858
Paul Mackerras712fcc02005-11-30 09:28:16 +11005859 label $top.ddisp -text "Diff display options"
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04005860 $top.ddisp configure -font $uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +11005861 grid $top.ddisp - -sticky w -pady 10
5862 label $top.diffoptl -text "Options for diff program" \
5863 -font optionfont
5864 entry $top.diffopt -width 20 -textvariable diffopts
5865 grid x $top.diffoptl $top.diffopt -sticky w
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005866 frame $top.ntag
5867 label $top.ntag.l -text "Display nearby tags" -font optionfont
5868 checkbutton $top.ntag.b -variable showneartags
5869 pack $top.ntag.b $top.ntag.l -side left
5870 grid x $top.ntag -sticky w
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005871
5872 label $top.cdisp -text "Colors: press to choose"
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04005873 $top.cdisp configure -font $uifont
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005874 grid $top.cdisp - -sticky w -pady 10
5875 label $top.bg -padx 40 -relief sunk -background $bgcolor
5876 button $top.bgbut -text "Background" -font optionfont \
5877 -command [list choosecolor bgcolor 0 $top.bg background setbg]
5878 grid x $top.bgbut $top.bg -sticky w
5879 label $top.fg -padx 40 -relief sunk -background $fgcolor
5880 button $top.fgbut -text "Foreground" -font optionfont \
5881 -command [list choosecolor fgcolor 0 $top.fg foreground setfg]
5882 grid x $top.fgbut $top.fg -sticky w
5883 label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
5884 button $top.diffoldbut -text "Diff: old lines" -font optionfont \
5885 -command [list choosecolor diffcolors 0 $top.diffold "diff old lines" \
5886 [list $ctext tag conf d0 -foreground]]
5887 grid x $top.diffoldbut $top.diffold -sticky w
5888 label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
5889 button $top.diffnewbut -text "Diff: new lines" -font optionfont \
5890 -command [list choosecolor diffcolors 1 $top.diffnew "diff new lines" \
5891 [list $ctext tag conf d1 -foreground]]
5892 grid x $top.diffnewbut $top.diffnew -sticky w
5893 label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
5894 button $top.hunksepbut -text "Diff: hunk header" -font optionfont \
5895 -command [list choosecolor diffcolors 2 $top.hunksep \
5896 "diff hunk header" \
5897 [list $ctext tag conf hunksep -foreground]]
5898 grid x $top.hunksepbut $top.hunksep -sticky w
5899
Paul Mackerras712fcc02005-11-30 09:28:16 +11005900 frame $top.buts
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04005901 button $top.buts.ok -text "OK" -command prefsok -default active
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04005902 $top.buts.ok configure -font $uifont
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04005903 button $top.buts.can -text "Cancel" -command prefscan -default normal
Eygene Ryabinkind59c4b62007-03-27 14:36:12 +04005904 $top.buts.can configure -font $uifont
Paul Mackerras712fcc02005-11-30 09:28:16 +11005905 grid $top.buts.ok $top.buts.can
5906 grid columnconfigure $top.buts 0 -weight 1 -uniform a
5907 grid columnconfigure $top.buts 1 -weight 1 -uniform a
5908 grid $top.buts - - -pady 10 -sticky ew
Eygene Ryabinkin3a950e92007-03-27 14:36:59 +04005909 bind $top <Visibility> "focus $top.buts.ok"
Paul Mackerras712fcc02005-11-30 09:28:16 +11005910}
5911
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10005912proc choosecolor {v vi w x cmd} {
5913 global $v
5914
5915 set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \
5916 -title "Gitk: choose color for $x"]
5917 if {$c eq {}} return
5918 $w conf -background $c
5919 lset $v $vi $c
5920 eval $cmd $c
5921}
5922
5923proc setbg {c} {
5924 global bglist
5925
5926 foreach w $bglist {
5927 $w conf -background $c
5928 }
5929}
5930
5931proc setfg {c} {
5932 global fglist canv
5933
5934 foreach w $fglist {
5935 $w conf -foreground $c
5936 }
5937 allcanvs itemconf text -fill $c
5938 $canv itemconf circle -outline $c
5939}
5940
Paul Mackerras712fcc02005-11-30 09:28:16 +11005941proc prefscan {} {
Paul Mackerras60f7a7d2006-05-26 10:43:47 +10005942 global maxwidth maxgraphpct diffopts
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005943 global oldprefs prefstop showneartags
Paul Mackerras712fcc02005-11-30 09:28:16 +11005944
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005945 foreach v {maxwidth maxgraphpct diffopts showneartags} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11005946 set $v $oldprefs($v)
5947 }
5948 catch {destroy $prefstop}
5949 unset prefstop
5950}
5951
5952proc prefsok {} {
5953 global maxwidth maxgraphpct
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005954 global oldprefs prefstop showneartags
Paul Mackerras712fcc02005-11-30 09:28:16 +11005955
5956 catch {destroy $prefstop}
5957 unset prefstop
5958 if {$maxwidth != $oldprefs(maxwidth)
5959 || $maxgraphpct != $oldprefs(maxgraphpct)} {
5960 redisplay
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10005961 } elseif {$showneartags != $oldprefs(showneartags)} {
5962 reselectline
Paul Mackerras712fcc02005-11-30 09:28:16 +11005963 }
5964}
5965
5966proc formatdate {d} {
5967 return [clock format $d -format "%Y-%m-%d %H:%M:%S"]
Paul Mackerras232475d2005-11-15 10:34:03 +11005968}
5969
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11005970# This list of encoding names and aliases is distilled from
5971# http://www.iana.org/assignments/character-sets.
5972# Not all of them are supported by Tcl.
5973set encoding_aliases {
5974 { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII
5975 ISO646-US US-ASCII us IBM367 cp367 csASCII }
5976 { ISO-10646-UTF-1 csISO10646UTF1 }
5977 { ISO_646.basic:1983 ref csISO646basic1983 }
5978 { INVARIANT csINVARIANT }
5979 { ISO_646.irv:1983 iso-ir-2 irv csISO2IntlRefVersion }
5980 { BS_4730 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom }
5981 { NATS-SEFI iso-ir-8-1 csNATSSEFI }
5982 { NATS-SEFI-ADD iso-ir-8-2 csNATSSEFIADD }
5983 { NATS-DANO iso-ir-9-1 csNATSDANO }
5984 { NATS-DANO-ADD iso-ir-9-2 csNATSDANOADD }
5985 { SEN_850200_B iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish }
5986 { SEN_850200_C iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames }
5987 { KS_C_5601-1987 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 }
5988 { ISO-2022-KR csISO2022KR }
5989 { EUC-KR csEUCKR }
5990 { ISO-2022-JP csISO2022JP }
5991 { ISO-2022-JP-2 csISO2022JP2 }
5992 { JIS_C6220-1969-jp JIS_C6220-1969 iso-ir-13 katakana x0201-7
5993 csISO13JISC6220jp }
5994 { JIS_C6220-1969-ro iso-ir-14 jp ISO646-JP csISO14JISC6220ro }
5995 { IT iso-ir-15 ISO646-IT csISO15Italian }
5996 { PT iso-ir-16 ISO646-PT csISO16Portuguese }
5997 { ES iso-ir-17 ISO646-ES csISO17Spanish }
5998 { greek7-old iso-ir-18 csISO18Greek7Old }
5999 { latin-greek iso-ir-19 csISO19LatinGreek }
6000 { DIN_66003 iso-ir-21 de ISO646-DE csISO21German }
6001 { NF_Z_62-010_(1973) iso-ir-25 ISO646-FR1 csISO25French }
6002 { Latin-greek-1 iso-ir-27 csISO27LatinGreek1 }
6003 { ISO_5427 iso-ir-37 csISO5427Cyrillic }
6004 { JIS_C6226-1978 iso-ir-42 csISO42JISC62261978 }
6005 { BS_viewdata iso-ir-47 csISO47BSViewdata }
6006 { INIS iso-ir-49 csISO49INIS }
6007 { INIS-8 iso-ir-50 csISO50INIS8 }
6008 { INIS-cyrillic iso-ir-51 csISO51INISCyrillic }
6009 { ISO_5427:1981 iso-ir-54 ISO5427Cyrillic1981 }
6010 { ISO_5428:1980 iso-ir-55 csISO5428Greek }
6011 { GB_1988-80 iso-ir-57 cn ISO646-CN csISO57GB1988 }
6012 { GB_2312-80 iso-ir-58 chinese csISO58GB231280 }
6013 { NS_4551-1 iso-ir-60 ISO646-NO no csISO60DanishNorwegian
6014 csISO60Norwegian1 }
6015 { NS_4551-2 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 }
6016 { NF_Z_62-010 iso-ir-69 ISO646-FR fr csISO69French }
6017 { videotex-suppl iso-ir-70 csISO70VideotexSupp1 }
6018 { PT2 iso-ir-84 ISO646-PT2 csISO84Portuguese2 }
6019 { ES2 iso-ir-85 ISO646-ES2 csISO85Spanish2 }
6020 { MSZ_7795.3 iso-ir-86 ISO646-HU hu csISO86Hungarian }
6021 { JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 }
6022 { greek7 iso-ir-88 csISO88Greek7 }
6023 { ASMO_449 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 }
6024 { iso-ir-90 csISO90 }
6025 { JIS_C6229-1984-a iso-ir-91 jp-ocr-a csISO91JISC62291984a }
6026 { JIS_C6229-1984-b iso-ir-92 ISO646-JP-OCR-B jp-ocr-b
6027 csISO92JISC62991984b }
6028 { JIS_C6229-1984-b-add iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd }
6029 { JIS_C6229-1984-hand iso-ir-94 jp-ocr-hand csISO94JIS62291984hand }
6030 { JIS_C6229-1984-hand-add iso-ir-95 jp-ocr-hand-add
6031 csISO95JIS62291984handadd }
6032 { JIS_C6229-1984-kana iso-ir-96 csISO96JISC62291984kana }
6033 { ISO_2033-1983 iso-ir-98 e13b csISO2033 }
6034 { ANSI_X3.110-1983 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS }
6035 { ISO_8859-1:1987 iso-ir-100 ISO_8859-1 ISO-8859-1 latin1 l1 IBM819
6036 CP819 csISOLatin1 }
6037 { ISO_8859-2:1987 iso-ir-101 ISO_8859-2 ISO-8859-2 latin2 l2 csISOLatin2 }
6038 { T.61-7bit iso-ir-102 csISO102T617bit }
6039 { T.61-8bit T.61 iso-ir-103 csISO103T618bit }
6040 { ISO_8859-3:1988 iso-ir-109 ISO_8859-3 ISO-8859-3 latin3 l3 csISOLatin3 }
6041 { ISO_8859-4:1988 iso-ir-110 ISO_8859-4 ISO-8859-4 latin4 l4 csISOLatin4 }
6042 { ECMA-cyrillic iso-ir-111 KOI8-E csISO111ECMACyrillic }
6043 { CSA_Z243.4-1985-1 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 }
6044 { CSA_Z243.4-1985-2 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 }
6045 { CSA_Z243.4-1985-gr iso-ir-123 csISO123CSAZ24341985gr }
6046 { ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ISO-8859-6 ECMA-114 ASMO-708
6047 arabic csISOLatinArabic }
6048 { ISO_8859-6-E csISO88596E ISO-8859-6-E }
6049 { ISO_8859-6-I csISO88596I ISO-8859-6-I }
6050 { ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ISO-8859-7 ELOT_928 ECMA-118
6051 greek greek8 csISOLatinGreek }
6052 { T.101-G2 iso-ir-128 csISO128T101G2 }
6053 { ISO_8859-8:1988 iso-ir-138 ISO_8859-8 ISO-8859-8 hebrew
6054 csISOLatinHebrew }
6055 { ISO_8859-8-E csISO88598E ISO-8859-8-E }
6056 { ISO_8859-8-I csISO88598I ISO-8859-8-I }
6057 { CSN_369103 iso-ir-139 csISO139CSN369103 }
6058 { JUS_I.B1.002 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 }
6059 { ISO_6937-2-add iso-ir-142 csISOTextComm }
6060 { IEC_P27-1 iso-ir-143 csISO143IECP271 }
6061 { ISO_8859-5:1988 iso-ir-144 ISO_8859-5 ISO-8859-5 cyrillic
6062 csISOLatinCyrillic }
6063 { JUS_I.B1.003-serb iso-ir-146 serbian csISO146Serbian }
6064 { JUS_I.B1.003-mac macedonian iso-ir-147 csISO147Macedonian }
6065 { ISO_8859-9:1989 iso-ir-148 ISO_8859-9 ISO-8859-9 latin5 l5 csISOLatin5 }
6066 { greek-ccitt iso-ir-150 csISO150 csISO150GreekCCITT }
6067 { NC_NC00-10:81 cuba iso-ir-151 ISO646-CU csISO151Cuba }
6068 { ISO_6937-2-25 iso-ir-152 csISO6937Add }
6069 { GOST_19768-74 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 }
6070 { ISO_8859-supp iso-ir-154 latin1-2-5 csISO8859Supp }
6071 { ISO_10367-box iso-ir-155 csISO10367Box }
6072 { ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 }
6073 { latin-lap lap iso-ir-158 csISO158Lap }
6074 { JIS_X0212-1990 x0212 iso-ir-159 csISO159JISX02121990 }
6075 { DS_2089 DS2089 ISO646-DK dk csISO646Danish }
6076 { us-dk csUSDK }
6077 { dk-us csDKUS }
6078 { JIS_X0201 X0201 csHalfWidthKatakana }
6079 { KSC5636 ISO646-KR csKSC5636 }
6080 { ISO-10646-UCS-2 csUnicode }
6081 { ISO-10646-UCS-4 csUCS4 }
6082 { DEC-MCS dec csDECMCS }
6083 { hp-roman8 roman8 r8 csHPRoman8 }
6084 { macintosh mac csMacintosh }
6085 { IBM037 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl
6086 csIBM037 }
6087 { IBM038 EBCDIC-INT cp038 csIBM038 }
6088 { IBM273 CP273 csIBM273 }
6089 { IBM274 EBCDIC-BE CP274 csIBM274 }
6090 { IBM275 EBCDIC-BR cp275 csIBM275 }
6091 { IBM277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 }
6092 { IBM278 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 }
6093 { IBM280 CP280 ebcdic-cp-it csIBM280 }
6094 { IBM281 EBCDIC-JP-E cp281 csIBM281 }
6095 { IBM284 CP284 ebcdic-cp-es csIBM284 }
6096 { IBM285 CP285 ebcdic-cp-gb csIBM285 }
6097 { IBM290 cp290 EBCDIC-JP-kana csIBM290 }
6098 { IBM297 cp297 ebcdic-cp-fr csIBM297 }
6099 { IBM420 cp420 ebcdic-cp-ar1 csIBM420 }
6100 { IBM423 cp423 ebcdic-cp-gr csIBM423 }
6101 { IBM424 cp424 ebcdic-cp-he csIBM424 }
6102 { IBM437 cp437 437 csPC8CodePage437 }
6103 { IBM500 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 }
6104 { IBM775 cp775 csPC775Baltic }
6105 { IBM850 cp850 850 csPC850Multilingual }
6106 { IBM851 cp851 851 csIBM851 }
6107 { IBM852 cp852 852 csPCp852 }
6108 { IBM855 cp855 855 csIBM855 }
6109 { IBM857 cp857 857 csIBM857 }
6110 { IBM860 cp860 860 csIBM860 }
6111 { IBM861 cp861 861 cp-is csIBM861 }
6112 { IBM862 cp862 862 csPC862LatinHebrew }
6113 { IBM863 cp863 863 csIBM863 }
6114 { IBM864 cp864 csIBM864 }
6115 { IBM865 cp865 865 csIBM865 }
6116 { IBM866 cp866 866 csIBM866 }
6117 { IBM868 CP868 cp-ar csIBM868 }
6118 { IBM869 cp869 869 cp-gr csIBM869 }
6119 { IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 }
6120 { IBM871 CP871 ebcdic-cp-is csIBM871 }
6121 { IBM880 cp880 EBCDIC-Cyrillic csIBM880 }
6122 { IBM891 cp891 csIBM891 }
6123 { IBM903 cp903 csIBM903 }
6124 { IBM904 cp904 904 csIBBM904 }
6125 { IBM905 CP905 ebcdic-cp-tr csIBM905 }
6126 { IBM918 CP918 ebcdic-cp-ar2 csIBM918 }
6127 { IBM1026 CP1026 csIBM1026 }
6128 { EBCDIC-AT-DE csIBMEBCDICATDE }
6129 { EBCDIC-AT-DE-A csEBCDICATDEA }
6130 { EBCDIC-CA-FR csEBCDICCAFR }
6131 { EBCDIC-DK-NO csEBCDICDKNO }
6132 { EBCDIC-DK-NO-A csEBCDICDKNOA }
6133 { EBCDIC-FI-SE csEBCDICFISE }
6134 { EBCDIC-FI-SE-A csEBCDICFISEA }
6135 { EBCDIC-FR csEBCDICFR }
6136 { EBCDIC-IT csEBCDICIT }
6137 { EBCDIC-PT csEBCDICPT }
6138 { EBCDIC-ES csEBCDICES }
6139 { EBCDIC-ES-A csEBCDICESA }
6140 { EBCDIC-ES-S csEBCDICESS }
6141 { EBCDIC-UK csEBCDICUK }
6142 { EBCDIC-US csEBCDICUS }
6143 { UNKNOWN-8BIT csUnknown8BiT }
6144 { MNEMONIC csMnemonic }
6145 { MNEM csMnem }
6146 { VISCII csVISCII }
6147 { VIQR csVIQR }
6148 { KOI8-R csKOI8R }
6149 { IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro }
6150 { IBM00924 CCSID00924 CP00924 ebcdic-Latin9--euro }
6151 { IBM01140 CCSID01140 CP01140 ebcdic-us-37+euro }
6152 { IBM01141 CCSID01141 CP01141 ebcdic-de-273+euro }
6153 { IBM01142 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro }
6154 { IBM01143 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro }
6155 { IBM01144 CCSID01144 CP01144 ebcdic-it-280+euro }
6156 { IBM01145 CCSID01145 CP01145 ebcdic-es-284+euro }
6157 { IBM01146 CCSID01146 CP01146 ebcdic-gb-285+euro }
6158 { IBM01147 CCSID01147 CP01147 ebcdic-fr-297+euro }
6159 { IBM01148 CCSID01148 CP01148 ebcdic-international-500+euro }
6160 { IBM01149 CCSID01149 CP01149 ebcdic-is-871+euro }
6161 { IBM1047 IBM-1047 }
6162 { PTCP154 csPTCP154 PT154 CP154 Cyrillic-Asian }
6163 { Amiga-1251 Ami1251 Amiga1251 Ami-1251 }
6164 { UNICODE-1-1 csUnicode11 }
6165 { CESU-8 csCESU-8 }
6166 { BOCU-1 csBOCU-1 }
6167 { UNICODE-1-1-UTF-7 csUnicode11UTF7 }
6168 { ISO-8859-14 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic
6169 l8 }
6170 { ISO-8859-15 ISO_8859-15 Latin-9 }
6171 { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
6172 { GBK CP936 MS936 windows-936 }
6173 { JIS_Encoding csJISEncoding }
6174 { Shift_JIS MS_Kanji csShiftJIS }
6175 { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
6176 EUC-JP }
6177 { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
6178 { ISO-10646-UCS-Basic csUnicodeASCII }
6179 { ISO-10646-Unicode-Latin1 csUnicodeLatin1 ISO-10646 }
6180 { ISO-Unicode-IBM-1261 csUnicodeIBM1261 }
6181 { ISO-Unicode-IBM-1268 csUnicodeIBM1268 }
6182 { ISO-Unicode-IBM-1276 csUnicodeIBM1276 }
6183 { ISO-Unicode-IBM-1264 csUnicodeIBM1264 }
6184 { ISO-Unicode-IBM-1265 csUnicodeIBM1265 }
6185 { ISO-8859-1-Windows-3.0-Latin-1 csWindows30Latin1 }
6186 { ISO-8859-1-Windows-3.1-Latin-1 csWindows31Latin1 }
6187 { ISO-8859-2-Windows-Latin-2 csWindows31Latin2 }
6188 { ISO-8859-9-Windows-Latin-5 csWindows31Latin5 }
6189 { Adobe-Standard-Encoding csAdobeStandardEncoding }
6190 { Ventura-US csVenturaUS }
6191 { Ventura-International csVenturaInternational }
6192 { PC8-Danish-Norwegian csPC8DanishNorwegian }
6193 { PC8-Turkish csPC8Turkish }
6194 { IBM-Symbols csIBMSymbols }
6195 { IBM-Thai csIBMThai }
6196 { HP-Legal csHPLegal }
6197 { HP-Pi-font csHPPiFont }
6198 { HP-Math8 csHPMath8 }
6199 { Adobe-Symbol-Encoding csHPPSMath }
6200 { HP-DeskTop csHPDesktop }
6201 { Ventura-Math csVenturaMath }
6202 { Microsoft-Publishing csMicrosoftPublishing }
6203 { Windows-31J csWindows31J }
6204 { GB2312 csGB2312 }
6205 { Big5 csBig5 }
6206}
6207
6208proc tcl_encoding {enc} {
6209 global encoding_aliases
6210 set names [encoding names]
6211 set lcnames [string tolower $names]
6212 set enc [string tolower $enc]
6213 set i [lsearch -exact $lcnames $enc]
6214 if {$i < 0} {
6215 # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
6216 if {[regsub {^iso[-_]} $enc iso encx]} {
6217 set i [lsearch -exact $lcnames $encx]
6218 }
6219 }
6220 if {$i < 0} {
6221 foreach l $encoding_aliases {
6222 set ll [string tolower $l]
6223 if {[lsearch -exact $ll $enc] < 0} continue
6224 # look through the aliases for one that tcl knows about
6225 foreach e $ll {
6226 set i [lsearch -exact $lcnames $e]
6227 if {$i < 0} {
6228 if {[regsub {^iso[-_]} $e iso ex]} {
6229 set i [lsearch -exact $lcnames $ex]
6230 }
6231 }
6232 if {$i >= 0} break
6233 }
6234 break
6235 }
6236 }
6237 if {$i >= 0} {
6238 return [lindex $names $i]
6239 }
6240 return {}
6241}
6242
Paul Mackerras1d10f362005-05-15 12:55:47 +00006243# defaults...
6244set datemode 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00006245set diffopts "-U 5 -p"
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03006246set wrcomcmd "git diff-tree --stdin -p --pretty"
Junio C Hamano671bc152005-11-27 16:12:51 -08006247
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11006248set gitencoding {}
Junio C Hamano671bc152005-11-27 16:12:51 -08006249catch {
Paul Mackerras27cb61c2007-02-15 08:54:34 +11006250 set gitencoding [exec git config --get i18n.commitencoding]
Junio C Hamano671bc152005-11-27 16:12:51 -08006251}
6252if {$gitencoding == ""} {
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11006253 set gitencoding "utf-8"
6254}
6255set tclencoding [tcl_encoding $gitencoding]
6256if {$tclencoding == {}} {
6257 puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
Junio C Hamano671bc152005-11-27 16:12:51 -08006258}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006259
6260set mainfont {Helvetica 9}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006261set textfont {Courier 9}
Keith Packard4840be62006-04-04 00:19:45 -07006262set uifont {Helvetica 9 bold}
Paul Mackerrasb74fd572005-07-16 07:46:13 -04006263set findmergefiles 0
Paul Mackerras8d858d12005-08-05 09:52:16 +10006264set maxgraphpct 50
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10006265set maxwidth 16
Paul Mackerras232475d2005-11-15 10:34:03 +11006266set revlistorder 0
Paul Mackerras757f17b2005-11-21 09:56:07 +11006267set fastdate 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11006268set uparrowlen 7
6269set downarrowlen 7
6270set mingaplen 30
Paul Mackerrasf8b28a42006-05-01 09:50:57 +10006271set cmitmode "patch"
Sergey Vlasovf1b86292006-05-15 19:13:14 +04006272set wrapcomment "none"
Paul Mackerrasb8ab2e12006-06-03 19:11:13 +10006273set showneartags 1
Paul Mackerras1d10f362005-05-15 12:55:47 +00006274
6275set colors {green red blue magenta darkgrey brown orange}
Paul Mackerrasf8a2c0d2006-07-05 22:56:37 +10006276set bgcolor white
6277set fgcolor black
6278set diffcolors {red "#00a000" blue}
Paul Mackerras1d10f362005-05-15 12:55:47 +00006279
6280catch {source ~/.gitk}
6281
Paul Mackerras712fcc02005-11-30 09:28:16 +11006282font create optionfont -family sans-serif -size -12
Paul Mackerras17386062005-05-18 22:51:00 +00006283
Paul Mackerras1d10f362005-05-15 12:55:47 +00006284set revtreeargs {}
6285foreach arg $argv {
6286 switch -regexp -- $arg {
6287 "^$" { }
Paul Mackerras1d10f362005-05-15 12:55:47 +00006288 "^-d" { set datemode 1 }
Paul Mackerras1d10f362005-05-15 12:55:47 +00006289 default {
6290 lappend revtreeargs $arg
6291 }
6292 }
6293}
6294
Paul Mackerrasaa81d972006-02-28 11:27:12 +11006295# check that we can find a .git directory somewhere...
6296set gitdir [gitdir]
6297if {![file isdirectory $gitdir]} {
Paul Mackerrase54be9e2006-05-26 22:34:30 +10006298 show_error {} . "Cannot find the git directory \"$gitdir\"."
Paul Mackerrasaa81d972006-02-28 11:27:12 +11006299 exit 1
6300}
6301
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006302set cmdline_files {}
6303set i [lsearch -exact $revtreeargs "--"]
6304if {$i >= 0} {
6305 set cmdline_files [lrange $revtreeargs [expr {$i + 1}] end]
6306 set revtreeargs [lrange $revtreeargs 0 [expr {$i - 1}]]
6307} elseif {$revtreeargs ne {}} {
6308 if {[catch {
Timo Hirvonen8974c6f2006-05-24 10:57:40 +03006309 set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006310 set cmdline_files [split $f "\n"]
6311 set n [llength $cmdline_files]
6312 set revtreeargs [lrange $revtreeargs 0 end-$n]
6313 } err]} {
6314 # unfortunately we get both stdout and stderr in $err,
6315 # so look for "fatal:".
6316 set i [string first "fatal:" $err]
6317 if {$i > 0} {
Junio C Hamanob5e09632006-05-26 00:07:15 -07006318 set err [string range $err [expr {$i + 6}] end]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006319 }
Paul Mackerrase54be9e2006-05-26 22:34:30 +10006320 show_error {} . "Bad arguments to gitk:\n$err"
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006321 exit 1
6322 }
6323}
6324
Paul Mackerrasd6982062005-08-06 22:06:06 +10006325set history {}
6326set historyindex 0
Paul Mackerras908c3582006-05-20 09:38:11 +10006327set fh_serial 0
Paul Mackerras908c3582006-05-20 09:38:11 +10006328set nhl_names {}
Paul Mackerras63b79192006-05-20 21:31:52 +10006329set highlight_paths {}
Paul Mackerras1902c272006-05-25 21:25:13 +10006330set searchdirn -forwards
Paul Mackerras4e7d6772006-05-30 21:33:07 +10006331set boldrows {}
6332set boldnamerows {}
Paul Mackerrasd6982062005-08-06 22:06:06 +10006333
Paul Mackerras9f1afe02006-02-19 22:44:47 +11006334set optim_delay 16
6335
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006336set nextviewnum 1
6337set curview 0
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006338set selectedview 0
Paul Mackerras908c3582006-05-20 09:38:11 +10006339set selectedhlview None
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006340set viewfiles(0) {}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006341set viewperm(0) 0
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006342set viewargs(0) {}
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006343
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006344set cmdlineok 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00006345set stopped 0
Paul Mackerras0fba86b2005-05-16 23:54:58 +00006346set stuffsaved 0
Paul Mackerras74daedb2005-06-27 19:27:32 +10006347set patchnum 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00006348setcoords
Paul Mackerrasd94f8cd2006-04-06 10:18:23 +10006349makewindow
Doug Maxey6c283322006-12-10 14:31:46 -06006350wm title . "[file tail $argv0]: [file tail [pwd]]"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00006351readrefs
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10006352
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006353if {$cmdline_files ne {} || $revtreeargs ne {}} {
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006354 # create a view for the files/dirs specified on the command line
6355 set curview 1
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006356 set selectedview 1
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006357 set nextviewnum 2
6358 set viewname(1) "Command line"
6359 set viewfiles(1) $cmdline_files
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006360 set viewargs(1) $revtreeargs
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006361 set viewperm(1) 0
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10006362 addviewmenu 1
Paul Mackerras3cd204e2006-11-23 21:06:16 +11006363 .bar.view entryconf Edit* -state normal
6364 .bar.view entryconf Delete* -state normal
Paul Mackerras50b44ec2006-04-04 10:16:22 +10006365}
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006366
6367if {[info exists permviews]} {
6368 foreach v $permviews {
6369 set n $nextviewnum
6370 incr nextviewnum
6371 set viewname($n) [lindex $v 0]
6372 set viewfiles($n) [lindex $v 1]
Paul Mackerras098dd8a2006-05-03 09:32:53 +10006373 set viewargs($n) [lindex $v 2]
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006374 set viewperm($n) 1
Paul Mackerrasda7c24d2006-05-02 11:15:29 +10006375 addviewmenu $n
Paul Mackerrasa90a6d22006-04-25 17:12:46 +10006376 }
6377}
Paul Mackerrasa8aaf192006-04-23 22:45:55 +10006378getcommits