blob: 3b8ecd03c5ef52c7f8e7330da131e574173c4329 [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
5# Copyright (C) 2005 Paul Mackerras. All rights reserved.
6# 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 {
15 return ".git"
16 }
17}
18
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +010019proc parse_args {rargs} {
20 global parsed_args
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +000021
Paul Mackerras418c4c72006-02-07 09:10:18 +110022 if {[catch {
Paul Mackerrasb490a992005-06-22 10:25:38 +100023 set parse_args [concat --default HEAD $rargs]
Paul Mackerras2efef4b2005-06-21 10:20:04 +100024 set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
Paul Mackerras418c4c72006-02-07 09:10:18 +110025 }]} {
Paul Mackerrasb490a992005-06-22 10:25:38 +100026 # if git-rev-parse failed for some reason...
Paul Mackerras2efef4b2005-06-21 10:20:04 +100027 if {$rargs == {}} {
28 set rargs HEAD
29 }
Paul Mackerrasb490a992005-06-22 10:25:38 +100030 set parsed_args $rargs
Paul Mackerras2efef4b2005-06-21 10:20:04 +100031 }
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +010032 return $parsed_args
33}
34
Paul Mackerras38ad0912005-12-01 22:42:46 +110035proc start_rev_list {rlargs} {
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +010036 global startmsecs nextupdate ncmupdate
Paul Mackerras9f1afe02006-02-19 22:44:47 +110037 global commfd leftover tclencoding datemode
Paul Mackerras8ed16482006-03-02 22:56:44 +110038 global commitdata
Paul Mackerras38ad0912005-12-01 22:42:46 +110039
40 set startmsecs [clock clicks -milliseconds]
41 set nextupdate [expr {$startmsecs + 100}]
42 set ncmupdate 1
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +110043 initlayout
Paul Mackerras9f1afe02006-02-19 22:44:47 +110044 set order "--topo-order"
45 if {$datemode} {
46 set order "--date-order"
47 }
Paul Mackerras418c4c72006-02-07 09:10:18 +110048 if {[catch {
Paul Mackerras9f1afe02006-02-19 22:44:47 +110049 set commfd [open [concat | git-rev-list --header $order \
Paul Mackerras38ad0912005-12-01 22:42:46 +110050 --parents $rlargs] r]
Paul Mackerras418c4c72006-02-07 09:10:18 +110051 } err]} {
Paul Mackerras38ad0912005-12-01 22:42:46 +110052 puts stderr "Error executing git-rev-list: $err"
53 exit 1
54 }
55 set leftover {}
Paul Mackerras8ed16482006-03-02 22:56:44 +110056 set commitdata {}
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +110057 fconfigure $commfd -blocking 0 -translation lf
58 if {$tclencoding != {}} {
59 fconfigure $commfd -encoding $tclencoding
60 }
Paul Mackerras38ad0912005-12-01 22:42:46 +110061 fileevent $commfd readable [list getcommitlines $commfd]
62 . config -cursor watch
63 settextcursor watch
64}
65
66proc getcommits {rargs} {
Paul Mackerrasaa81d972006-02-28 11:27:12 +110067 global phase canv mainfont
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +010068
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +010069 set phase getcommits
Paul Mackerras38ad0912005-12-01 22:42:46 +110070 start_rev_list [parse_args $rargs]
Paul Mackerras1d10f362005-05-15 12:55:47 +000071 $canv delete all
72 $canv create text 3 3 -anchor nw -text "Reading commits..." \
73 -font $mainfont -tags textitems
74}
75
Paul Mackerrasb490a992005-06-22 10:25:38 +100076proc getcommitlines {commfd} {
Paul Mackerras8ed16482006-03-02 22:56:44 +110077 global commitlisted nextupdate
78 global leftover
79 global displayorder commitidx commitrow commitdata
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +000080
Paul Mackerrasb490a992005-06-22 10:25:38 +100081 set stuff [read $commfd]
82 if {$stuff == {}} {
Paul Mackerras1d10f362005-05-15 12:55:47 +000083 if {![eof $commfd]} return
Paul Mackerrasf0654862005-07-18 14:29:03 -040084 # set it blocking so we wait for the process to terminate
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +000085 fconfigure $commfd -blocking 1
Paul Mackerras1d10f362005-05-15 12:55:47 +000086 if {![catch {close $commfd} err]} {
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +000087 after idle finishcommits
Paul Mackerras1d10f362005-05-15 12:55:47 +000088 return
89 }
Paul Mackerras9a40c502005-05-12 23:46:16 +000090 if {[string range $err 0 4] == "usage"} {
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +000091 set err \
Jeff Hobbs2ed49d52005-11-22 17:39:53 -080092 "Gitk: error reading commits: bad arguments to git-rev-list.\
93 (Note: arguments to gitk are passed to git-rev-list\
94 to allow selection of commits to be displayed.)"
Paul Mackerras9a40c502005-05-12 23:46:16 +000095 } else {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +000096 set err "Error reading commits: $err"
Paul Mackerras9a40c502005-05-12 23:46:16 +000097 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +000098 error_popup $err
Paul Mackerras1d10f362005-05-15 12:55:47 +000099 exit 1
Paul Mackerras9a40c502005-05-12 23:46:16 +0000100 }
Paul Mackerrasb490a992005-06-22 10:25:38 +1000101 set start 0
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100102 set gotsome 0
Paul Mackerrasb490a992005-06-22 10:25:38 +1000103 while 1 {
104 set i [string first "\0" $stuff $start]
105 if {$i < 0} {
Paul Mackerras7e952e72005-06-27 20:04:26 +1000106 append leftover [string range $stuff $start end]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100107 break
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000108 }
Paul Mackerrasb490a992005-06-22 10:25:38 +1000109 if {$start == 0} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100110 set cmit $leftover
111 append cmit [string range $stuff 0 [expr {$i - 1}]]
Paul Mackerras7e952e72005-06-27 20:04:26 +1000112 set leftover {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100113 } else {
114 set cmit [string range $stuff $start [expr {$i - 1}]]
Paul Mackerrasb490a992005-06-22 10:25:38 +1000115 }
116 set start [expr {$i + 1}]
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000117 set j [string first "\n" $cmit]
118 set ok 0
119 if {$j >= 0} {
120 set ids [string range $cmit 0 [expr {$j - 1}]]
121 set ok 1
122 foreach id $ids {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100123 if {[string length $id] != 40} {
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000124 set ok 0
125 break
126 }
127 }
128 }
129 if {!$ok} {
Paul Mackerras7e952e72005-06-27 20:04:26 +1000130 set shortcmit $cmit
131 if {[string length $shortcmit] > 80} {
132 set shortcmit "[string range $shortcmit 0 80]..."
133 }
134 error_popup "Can't parse git-rev-list output: {$shortcmit}"
Paul Mackerrasb490a992005-06-22 10:25:38 +1000135 exit 1
136 }
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000137 set id [lindex $ids 0]
138 set olds [lrange $ids 1 end]
Paul Mackerrasb490a992005-06-22 10:25:38 +1000139 set commitlisted($id) 1
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100140 updatechildren $id [lrange $ids 1 end]
Paul Mackerras8ed16482006-03-02 22:56:44 +1100141 lappend commitdata [string range $cmit [expr {$j + 1}] end]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100142 set commitrow($id) $commitidx
143 incr commitidx
144 lappend displayorder $id
145 set gotsome 1
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100146 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100147 if {$gotsome} {
148 layoutmore
149 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100150 if {[clock clicks -milliseconds] >= $nextupdate} {
151 doupdate 1
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000152 }
Paul Mackerrascfb45632005-05-31 12:14:42 +0000153}
154
Paul Mackerrasb6645502005-08-11 09:56:23 +1000155proc doupdate {reading} {
156 global commfd nextupdate numcommits ncmupdate
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000157
Paul Mackerrasb6645502005-08-11 09:56:23 +1000158 if {$reading} {
159 fileevent $commfd readable {}
160 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000161 update
Paul Mackerrasb6645502005-08-11 09:56:23 +1000162 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
163 if {$numcommits < 100} {
164 set ncmupdate [expr {$numcommits + 1}]
165 } elseif {$numcommits < 10000} {
166 set ncmupdate [expr {$numcommits + 10}]
167 } else {
168 set ncmupdate [expr {$numcommits + 100}]
169 }
170 if {$reading} {
171 fileevent $commfd readable [list getcommitlines $commfd]
172 }
Paul Mackerras1db95b02005-05-09 04:08:39 +0000173}
174
175proc readcommit {id} {
Paul Mackerras418c4c72006-02-07 09:10:18 +1100176 if {[catch {set contents [exec git-cat-file commit $id]}]} return
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100177 updatechildren $id {}
178 parsecommit $id $contents 0
Paul Mackerrasb490a992005-06-22 10:25:38 +1000179}
180
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +1100181proc updatecommits {rargs} {
Paul Mackerrasaa81d972006-02-28 11:27:12 +1100182 stopfindproc
183 foreach v {children nchildren parents nparents commitlisted
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100184 colormap selectedline matchinglines treediffs
185 mergefilelist currentid rowtextx commitrow
Paul Mackerrasaa81d972006-02-28 11:27:12 +1100186 rowidlist rowoffsets idrowranges idrangedrawn iddrawn
187 linesegends crossings cornercrossings} {
188 global $v
189 catch {unset $v}
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +1100190 }
Paul Mackerrasaa81d972006-02-28 11:27:12 +1100191 allcanvs delete all
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +1100192 readrefs
Paul Mackerrasaa81d972006-02-28 11:27:12 +1100193 getcommits $rargs
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +1100194}
195
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +0100196proc updatechildren {id olds} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100197 global children nchildren parents nparents
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +0000198
Paul Mackerrascfb45632005-05-31 12:14:42 +0000199 if {![info exists nchildren($id)]} {
200 set children($id) {}
201 set nchildren($id) 0
202 }
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000203 set parents($id) $olds
204 set nparents($id) [llength $olds]
205 foreach p $olds {
206 if {![info exists nchildren($p)]} {
207 set children($p) [list $id]
208 set nchildren($p) 1
Paul Mackerrase5ea7012005-08-18 20:40:39 +1000209 } elseif {[lsearch -exact $children($p) $id] < 0} {
210 lappend children($p) $id
211 incr nchildren($p)
Paul Mackerras244edd12005-08-17 21:27:55 +1000212 }
213 }
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +0100214}
215
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100216proc parsecommit {id contents listed} {
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +0100217 global commitinfo cdate
218
219 set inhdr 1
220 set comment {}
221 set headline {}
222 set auname {}
223 set audate {}
224 set comname {}
225 set comdate {}
Paul Mackerras232475d2005-11-15 10:34:03 +1100226 set hdrend [string first "\n\n" $contents]
227 if {$hdrend < 0} {
228 # should never happen...
229 set hdrend [string length $contents]
230 }
231 set header [string range $contents 0 [expr {$hdrend - 1}]]
232 set comment [string range $contents [expr {$hdrend + 2}] end]
233 foreach line [split $header "\n"] {
234 set tag [lindex $line 0]
235 if {$tag == "author"} {
236 set audate [lindex $line end-1]
237 set auname [lrange $line 1 end-2]
238 } elseif {$tag == "committer"} {
239 set comdate [lindex $line end-1]
240 set comname [lrange $line 1 end-2]
Paul Mackerras1db95b02005-05-09 04:08:39 +0000241 }
242 }
Paul Mackerras232475d2005-11-15 10:34:03 +1100243 set headline {}
244 # take the first line of the comment as the headline
245 set i [string first "\n" $comment]
246 if {$i >= 0} {
247 set headline [string trim [string range $comment 0 $i]]
Paul Mackerrasf6e28692005-11-20 23:08:22 +1100248 } else {
249 set headline $comment
Paul Mackerras232475d2005-11-15 10:34:03 +1100250 }
251 if {!$listed} {
252 # git-rev-list indents the comment by 4 spaces;
253 # if we got this via git-cat-file, add the indentation
254 set newcomment {}
255 foreach line [split $comment "\n"] {
256 append newcomment " "
257 append newcomment $line
Paul Mackerrasf6e28692005-11-20 23:08:22 +1100258 append newcomment "\n"
Paul Mackerras232475d2005-11-15 10:34:03 +1100259 }
260 set comment $newcomment
Paul Mackerras1db95b02005-05-09 04:08:39 +0000261 }
262 if {$comdate != {}} {
Paul Mackerrascfb45632005-05-31 12:14:42 +0000263 set cdate($id) $comdate
Paul Mackerras1db95b02005-05-09 04:08:39 +0000264 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +0000265 set commitinfo($id) [list $headline $auname $audate \
266 $comname $comdate $comment]
Paul Mackerras1db95b02005-05-09 04:08:39 +0000267}
268
Paul Mackerras8ed16482006-03-02 22:56:44 +1100269proc getcommit {id {row {}}} {
270 global commitdata commitrow commitinfo nparents
271
272 if {$row eq {}} {
273 if {![info exists commitrow($id)]} {return 0}
274 set row $commitrow($id)
275 }
276 if {$row < [llength $commitdata]} {
277 parsecommit $id [lindex $commitdata $row] 1
278 } else {
279 readcommit $id
280 if {![info exists commitinfo($id)]} {
281 set commitinfo($id) {"No commit information available"}
282 set nparents($id) 0
283 }
284 }
285 return 1
286}
287
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000288proc readrefs {} {
Paul Mackerras106288c2005-08-19 23:11:39 +1000289 global tagids idtags headids idheads tagcontents
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +1000290 global otherrefids idotherrefs
291
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +0100292 foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
293 catch {unset $v}
294 }
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800295 set refd [open [list | git-ls-remote [gitdir]] r]
296 while {0 <= [set n [gets $refd line]]} {
297 if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \
298 match id path]} {
299 continue
300 }
301 if {![regexp {^(tags|heads)/(.*)$} $path match type name]} {
302 set type others
303 set name $path
304 }
305 if {$type == "tags"} {
306 set tagids($name) $id
307 lappend idtags($id) $name
308 set obj {}
309 set type {}
310 set tag {}
311 catch {
312 set commit [exec git-rev-parse "$id^0"]
313 if {"$commit" != "$id"} {
314 set tagids($name) $commit
315 lappend idtags($commit) $name
316 }
317 }
318 catch {
319 set tagcontents($name) [exec git-cat-file tag "$id"]
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +1000320 }
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800321 } elseif { $type == "heads" } {
322 set headids($name) $id
323 lappend idheads($id) $name
324 } else {
325 set otherrefids($name) $id
326 lappend idotherrefs($id) $name
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +1000327 }
328 }
Junio C Hamano36a7cad2005-11-18 23:54:17 -0800329 close $refd
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000330}
331
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000332proc error_popup msg {
333 set w .error
334 toplevel $w
335 wm transient $w .
336 message $w.m -text $msg -justify center -aspect 400
337 pack $w.m -side top -fill x -padx 20 -pady 20
338 button $w.ok -text OK -command "destroy $w"
339 pack $w.ok -side bottom -fill x
340 bind $w <Visibility> "grab $w; focus $w"
Martin Mares9f841cf2006-03-02 13:15:05 +0100341 bind $w <Key-Return> "destroy $w"
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000342 tkwait window $w
343}
344
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +0100345proc makewindow {rargs} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +0000346 global canv canv2 canv3 linespc charspc ctext cflist textfont
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400347 global findtype findtypemenu findloc findstring fstring geometry
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000348 global entries sha1entry sha1string sha1but
Paul Mackerras94a2eed2005-08-07 15:27:57 +1000349 global maincursor textcursor curtextcursor
Paul Mackerras712fcc02005-11-30 09:28:16 +1100350 global rowctxmenu mergemax
Paul Mackerras9a40c502005-05-12 23:46:16 +0000351
352 menu .bar
353 .bar add cascade -label "File" -menu .bar.file
354 menu .bar.file
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +0100355 .bar.file add command -label "Update" -command [list updatecommits $rargs]
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +1000356 .bar.file add command -label "Reread references" -command rereadrefs
Paul Mackerras1d10f362005-05-15 12:55:47 +0000357 .bar.file add command -label "Quit" -command doquit
Paul Mackerras712fcc02005-11-30 09:28:16 +1100358 menu .bar.edit
359 .bar add cascade -label "Edit" -menu .bar.edit
360 .bar.edit add command -label "Preferences" -command doprefs
Paul Mackerras9a40c502005-05-12 23:46:16 +0000361 menu .bar.help
362 .bar add cascade -label "Help" -menu .bar.help
363 .bar.help add command -label "About gitk" -command about
364 . configure -menu .bar
365
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000366 if {![info exists geometry(canv1)]} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800367 set geometry(canv1) [expr {45 * $charspc}]
368 set geometry(canv2) [expr {30 * $charspc}]
369 set geometry(canv3) [expr {15 * $charspc}]
370 set geometry(canvh) [expr {25 * $linespc + 4}]
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000371 set geometry(ctextw) 80
372 set geometry(ctexth) 30
373 set geometry(cflistw) 30
374 }
Paul Mackerras0327d272005-05-10 00:23:42 +0000375 panedwindow .ctop -orient vertical
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000376 if {[info exists geometry(width)]} {
377 .ctop conf -width $geometry(width) -height $geometry(height)
Paul Mackerras17386062005-05-18 22:51:00 +0000378 set texth [expr {$geometry(height) - $geometry(canvh) - 56}]
379 set geometry(ctexth) [expr {($texth - 8) /
380 [font metrics $textfont -linespace]}]
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000381 }
Paul Mackerras98f350e2005-05-15 05:56:51 +0000382 frame .ctop.top
383 frame .ctop.top.bar
384 pack .ctop.top.bar -side bottom -fill x
385 set cscroll .ctop.top.csb
386 scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
387 pack $cscroll -side right -fill y
388 panedwindow .ctop.top.clist -orient horizontal -sashpad 0 -handlesize 4
389 pack .ctop.top.clist -side top -fill both -expand 1
390 .ctop add .ctop.top
391 set canv .ctop.top.clist.canv
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000392 canvas $canv -height $geometry(canvh) -width $geometry(canv1) \
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000393 -bg white -bd 0 \
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100394 -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll"
Paul Mackerras98f350e2005-05-15 05:56:51 +0000395 .ctop.top.clist add $canv
396 set canv2 .ctop.top.clist.canv2
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000397 canvas $canv2 -height $geometry(canvh) -width $geometry(canv2) \
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000398 -bg white -bd 0 -yscrollincr $linespc
Paul Mackerras98f350e2005-05-15 05:56:51 +0000399 .ctop.top.clist add $canv2
400 set canv3 .ctop.top.clist.canv3
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000401 canvas $canv3 -height $geometry(canvh) -width $geometry(canv3) \
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000402 -bg white -bd 0 -yscrollincr $linespc
Paul Mackerras98f350e2005-05-15 05:56:51 +0000403 .ctop.top.clist add $canv3
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000404 bind .ctop.top.clist <Configure> {resizeclistpanes %W %w}
Paul Mackerras98f350e2005-05-15 05:56:51 +0000405
406 set sha1entry .ctop.top.bar.sha1
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000407 set entries $sha1entry
408 set sha1but .ctop.top.bar.sha1label
409 button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
410 -command gotocommit -width 8
411 $sha1but conf -disabledforeground [$sha1but cget -foreground]
Paul Mackerras98f350e2005-05-15 05:56:51 +0000412 pack .ctop.top.bar.sha1label -side left
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000413 entry $sha1entry -width 40 -font $textfont -textvariable sha1string
414 trace add variable sha1string write sha1change
Paul Mackerras98f350e2005-05-15 05:56:51 +0000415 pack $sha1entry -side left -pady 2
Paul Mackerrasd6982062005-08-06 22:06:06 +1000416
417 image create bitmap bm-left -data {
418 #define left_width 16
419 #define left_height 16
420 static unsigned char left_bits[] = {
421 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
422 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
423 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
424 }
425 image create bitmap bm-right -data {
426 #define right_width 16
427 #define right_height 16
428 static unsigned char right_bits[] = {
429 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
430 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
431 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
432 }
433 button .ctop.top.bar.leftbut -image bm-left -command goback \
434 -state disabled -width 26
435 pack .ctop.top.bar.leftbut -side left -fill y
436 button .ctop.top.bar.rightbut -image bm-right -command goforw \
437 -state disabled -width 26
438 pack .ctop.top.bar.rightbut -side left -fill y
439
Paul Mackerras98f350e2005-05-15 05:56:51 +0000440 button .ctop.top.bar.findbut -text "Find" -command dofind
441 pack .ctop.top.bar.findbut -side left
442 set findstring {}
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000443 set fstring .ctop.top.bar.findstring
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000444 lappend entries $fstring
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000445 entry $fstring -width 30 -font $textfont -textvariable findstring
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000446 pack $fstring -side left -expand 1 -fill x
Paul Mackerras98f350e2005-05-15 05:56:51 +0000447 set findtype Exact
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400448 set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \
449 findtype Exact IgnCase Regexp]
Paul Mackerras98f350e2005-05-15 05:56:51 +0000450 set findloc "All fields"
451 tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400452 Comments Author Committer Files Pickaxe
Paul Mackerras98f350e2005-05-15 05:56:51 +0000453 pack .ctop.top.bar.findloc -side right
454 pack .ctop.top.bar.findtype -side right
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400455 # for making sure type==Exact whenever loc==Pickaxe
456 trace add variable findloc write findlocchange
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000457
Paul Mackerras5ad588d2005-05-10 01:02:55 +0000458 panedwindow .ctop.cdet -orient horizontal
459 .ctop add .ctop.cdet
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000460 frame .ctop.cdet.left
461 set ctext .ctop.cdet.left.ctext
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000462 text $ctext -bg white -state disabled -font $textfont \
463 -width $geometry(ctextw) -height $geometry(ctexth) \
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -0700464 -yscrollcommand ".ctop.cdet.left.sb set" -wrap none
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000465 scrollbar .ctop.cdet.left.sb -command "$ctext yview"
466 pack .ctop.cdet.left.sb -side right -fill y
467 pack $ctext -side left -fill both -expand 1
468 .ctop.cdet add .ctop.cdet.left
469
Paul Mackerrasf0654862005-07-18 14:29:03 -0400470 $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
Paul Mackerras712fcc02005-11-30 09:28:16 +1100471 $ctext tag conf hunksep -fore blue
472 $ctext tag conf d0 -fore red
473 $ctext tag conf d1 -fore "#00a000"
474 $ctext tag conf m0 -fore red
475 $ctext tag conf m1 -fore blue
476 $ctext tag conf m2 -fore green
477 $ctext tag conf m3 -fore purple
478 $ctext tag conf m4 -fore brown
Paul Mackerrasb77b0272006-02-07 09:13:52 +1100479 $ctext tag conf m5 -fore "#009090"
480 $ctext tag conf m6 -fore magenta
481 $ctext tag conf m7 -fore "#808000"
482 $ctext tag conf m8 -fore "#009000"
483 $ctext tag conf m9 -fore "#ff0080"
484 $ctext tag conf m10 -fore cyan
485 $ctext tag conf m11 -fore "#b07070"
486 $ctext tag conf m12 -fore "#70b0f0"
487 $ctext tag conf m13 -fore "#70f0b0"
488 $ctext tag conf m14 -fore "#f0b070"
489 $ctext tag conf m15 -fore "#ff70b0"
Paul Mackerras712fcc02005-11-30 09:28:16 +1100490 $ctext tag conf mmax -fore darkgrey
Paul Mackerrasb77b0272006-02-07 09:13:52 +1100491 set mergemax 16
Paul Mackerras712fcc02005-11-30 09:28:16 +1100492 $ctext tag conf mresult -font [concat $textfont bold]
493 $ctext tag conf msep -font [concat $textfont bold]
494 $ctext tag conf found -back yellow
Paul Mackerrase5c2d852005-05-11 23:44:54 +0000495
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000496 frame .ctop.cdet.right
497 set cflist .ctop.cdet.right.cfiles
Paul Mackerras17386062005-05-18 22:51:00 +0000498 listbox $cflist -bg white -selectmode extended -width $geometry(cflistw) \
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000499 -yscrollcommand ".ctop.cdet.right.sb set"
500 scrollbar .ctop.cdet.right.sb -command "$cflist yview"
501 pack .ctop.cdet.right.sb -side right -fill y
502 pack $cflist -side left -fill both -expand 1
503 .ctop.cdet add .ctop.cdet.right
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000504 bind .ctop.cdet <Configure> {resizecdetpanes %W %w}
Paul Mackerrasd2610d12005-05-11 00:45:38 +0000505
Paul Mackerras0327d272005-05-10 00:23:42 +0000506 pack .ctop -side top -fill both -expand 1
Paul Mackerras1db95b02005-05-09 04:08:39 +0000507
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000508 bindall <1> {selcanvline %W %x %y}
509 #bindall <B1-Motion> {selcanvline %W %x %y}
Paul Mackerrascfb45632005-05-31 12:14:42 +0000510 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
511 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000512 bindall <2> "allcanvs scan mark 0 %y"
513 bindall <B2-Motion> "allcanvs scan dragto 0 %y"
Paul Mackerras17386062005-05-18 22:51:00 +0000514 bind . <Key-Up> "selnextline -1"
515 bind . <Key-Down> "selnextline 1"
Robert Suetterlin6e2dda32005-09-22 10:07:36 +1000516 bind . <Key-Right> "goforw"
517 bind . <Key-Left> "goback"
Paul Mackerrascfb45632005-05-31 12:14:42 +0000518 bind . <Key-Prior> "allcanvs yview scroll -1 pages"
519 bind . <Key-Next> "allcanvs yview scroll 1 pages"
520 bindkey <Key-Delete> "$ctext yview scroll -1 pages"
521 bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
522 bindkey <Key-space> "$ctext yview scroll 1 pages"
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000523 bindkey p "selnextline -1"
524 bindkey n "selnextline 1"
Robert Suetterlin6e2dda32005-09-22 10:07:36 +1000525 bindkey z "goback"
526 bindkey x "goforw"
527 bindkey i "selnextline -1"
528 bindkey k "selnextline 1"
529 bindkey j "goback"
530 bindkey l "goforw"
Paul Mackerrascfb45632005-05-31 12:14:42 +0000531 bindkey b "$ctext yview scroll -1 pages"
532 bindkey d "$ctext yview scroll 18 units"
533 bindkey u "$ctext yview scroll -18 units"
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400534 bindkey / {findnext 1}
535 bindkey <Key-Return> {findnext 0}
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000536 bindkey ? findprev
Paul Mackerras39ad8572005-05-19 12:35:53 +0000537 bindkey f nextfile
Paul Mackerras1d10f362005-05-15 12:55:47 +0000538 bind . <Control-q> doquit
Paul Mackerras98f350e2005-05-15 05:56:51 +0000539 bind . <Control-f> dofind
Paul Mackerrasb74fd572005-07-16 07:46:13 -0400540 bind . <Control-g> {findnext 0}
Paul Mackerras98f350e2005-05-15 05:56:51 +0000541 bind . <Control-r> findprev
Paul Mackerras1d10f362005-05-15 12:55:47 +0000542 bind . <Control-equal> {incrfont 1}
543 bind . <Control-KP_Add> {incrfont 1}
544 bind . <Control-minus> {incrfont -1}
545 bind . <Control-KP_Subtract> {incrfont -1}
Paul Mackerrase5c2d852005-05-11 23:44:54 +0000546 bind $cflist <<ListboxSelect>> listboxsel
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000547 bind . <Destroy> {savestuff %W}
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000548 bind . <Button-1> "click %W"
Paul Mackerras17386062005-05-18 22:51:00 +0000549 bind $fstring <Key-Return> dofind
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000550 bind $sha1entry <Key-Return> gotocommit
Paul Mackerrasee3dc722005-06-25 16:37:13 +1000551 bind $sha1entry <<PasteSelection>> clearsha1
Paul Mackerrasea13cba2005-06-16 10:54:04 +0000552
553 set maincursor [. cget -cursor]
554 set textcursor [$ctext cget -cursor]
Paul Mackerras94a2eed2005-08-07 15:27:57 +1000555 set curtextcursor $textcursor
Paul Mackerras84ba7342005-06-17 00:12:26 +0000556
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000557 set rowctxmenu .rowctxmenu
558 menu $rowctxmenu -tearoff 0
559 $rowctxmenu add command -label "Diff this -> selected" \
560 -command {diffvssel 0}
561 $rowctxmenu add command -label "Diff selected -> this" \
562 -command {diffvssel 1}
Paul Mackerras74daedb2005-06-27 19:27:32 +1000563 $rowctxmenu add command -label "Make patch" -command mkpatch
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +1000564 $rowctxmenu add command -label "Create tag" -command mktag
Paul Mackerras4a2139f2005-06-29 09:47:48 +1000565 $rowctxmenu add command -label "Write commit to file" -command writecommit
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000566}
567
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100568proc scrollcanv {cscroll f0 f1} {
569 $cscroll set $f0 $f1
570 drawfrac $f0 $f1
571}
572
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000573# when we make a key binding for the toplevel, make sure
574# it doesn't get triggered when that key is pressed in the
575# find string entry widget.
576proc bindkey {ev script} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000577 global entries
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000578 bind . $ev $script
579 set escript [bind Entry $ev]
580 if {$escript == {}} {
581 set escript [bind Entry <Key>]
582 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000583 foreach e $entries {
584 bind $e $ev "$escript; break"
585 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000586}
587
588# set the focus back to the toplevel for any click outside
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000589# the entry widgets
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000590proc click {w} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000591 global entries
592 foreach e $entries {
593 if {$w == $e} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000594 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +0000595 focus .
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000596}
597
598proc savestuff {w} {
599 global canv canv2 canv3 ctext cflist mainfont textfont
Paul Mackerras712fcc02005-11-30 09:28:16 +1100600 global stuffsaved findmergefiles maxgraphpct
Paul Mackerras04c13d32005-08-19 10:22:24 +1000601 global maxwidth
Paul Mackerras4ef17532005-07-27 22:16:51 -0500602
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000603 if {$stuffsaved} return
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +0000604 if {![winfo viewable .]} return
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000605 catch {
606 set f [open "~/.gitk-new" w]
Paul Mackerrasf0654862005-07-18 14:29:03 -0400607 puts $f [list set mainfont $mainfont]
608 puts $f [list set textfont $textfont]
609 puts $f [list set findmergefiles $findmergefiles]
Paul Mackerras8d858d12005-08-05 09:52:16 +1000610 puts $f [list set maxgraphpct $maxgraphpct]
Paul Mackerras04c13d32005-08-19 10:22:24 +1000611 puts $f [list set maxwidth $maxwidth]
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000612 puts $f "set geometry(width) [winfo width .ctop]"
613 puts $f "set geometry(height) [winfo height .ctop]"
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800614 puts $f "set geometry(canv1) [expr {[winfo width $canv]-2}]"
615 puts $f "set geometry(canv2) [expr {[winfo width $canv2]-2}]"
616 puts $f "set geometry(canv3) [expr {[winfo width $canv3]-2}]"
617 puts $f "set geometry(canvh) [expr {[winfo height $canv]-2}]"
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000618 set wid [expr {([winfo width $ctext] - 8) \
619 / [font measure $textfont "0"]}]
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000620 puts $f "set geometry(ctextw) $wid"
Paul Mackerras0fba86b2005-05-16 23:54:58 +0000621 set wid [expr {([winfo width $cflist] - 11) \
622 / [font measure [$cflist cget -font] "0"]}]
623 puts $f "set geometry(cflistw) $wid"
624 close $f
625 file rename -force "~/.gitk-new" "~/.gitk"
626 }
627 set stuffsaved 1
Paul Mackerras1db95b02005-05-09 04:08:39 +0000628}
629
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000630proc resizeclistpanes {win w} {
631 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +1100632 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000633 set s0 [$win sash coord 0]
634 set s1 [$win sash coord 1]
635 if {$w < 60} {
636 set sash0 [expr {int($w/2 - 2)}]
637 set sash1 [expr {int($w*5/6 - 2)}]
638 } else {
639 set factor [expr {1.0 * $w / $oldwidth($win)}]
640 set sash0 [expr {int($factor * [lindex $s0 0])}]
641 set sash1 [expr {int($factor * [lindex $s1 0])}]
642 if {$sash0 < 30} {
643 set sash0 30
644 }
645 if {$sash1 < $sash0 + 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800646 set sash1 [expr {$sash0 + 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000647 }
648 if {$sash1 > $w - 10} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800649 set sash1 [expr {$w - 10}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000650 if {$sash0 > $sash1 - 20} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800651 set sash0 [expr {$sash1 - 20}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000652 }
653 }
654 }
655 $win sash place 0 $sash0 [lindex $s0 1]
656 $win sash place 1 $sash1 [lindex $s1 1]
657 }
658 set oldwidth($win) $w
659}
660
661proc resizecdetpanes {win w} {
662 global oldwidth
Paul Mackerras418c4c72006-02-07 09:10:18 +1100663 if {[info exists oldwidth($win)]} {
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000664 set s0 [$win sash coord 0]
665 if {$w < 60} {
666 set sash0 [expr {int($w*3/4 - 2)}]
667 } else {
668 set factor [expr {1.0 * $w / $oldwidth($win)}]
669 set sash0 [expr {int($factor * [lindex $s0 0])}]
670 if {$sash0 < 45} {
671 set sash0 45
672 }
673 if {$sash0 > $w - 15} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -0800674 set sash0 [expr {$w - 15}]
Paul Mackerras43bddeb2005-05-15 23:19:18 +0000675 }
676 }
677 $win sash place 0 $sash0 [lindex $s0 1]
678 }
679 set oldwidth($win) $w
680}
681
Paul Mackerrasb5721c72005-05-10 12:08:22 +0000682proc allcanvs args {
683 global canv canv2 canv3
684 eval $canv $args
685 eval $canv2 $args
686 eval $canv3 $args
687}
688
689proc bindall {event action} {
690 global canv canv2 canv3
691 bind $canv $event $action
692 bind $canv2 $event $action
693 bind $canv3 $event $action
694}
695
Paul Mackerras9a40c502005-05-12 23:46:16 +0000696proc about {} {
697 set w .about
698 if {[winfo exists $w]} {
699 raise $w
700 return
701 }
702 toplevel $w
703 wm title $w "About gitk"
704 message $w.m -text {
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100705Gitk - a commit viewer for git
Paul Mackerras9a40c502005-05-12 23:46:16 +0000706
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100707Copyright © 2005-2006 Paul Mackerras
Paul Mackerras9a40c502005-05-12 23:46:16 +0000708
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +1000709Use and redistribute under the terms of the GNU General Public License} \
Paul Mackerras9a40c502005-05-12 23:46:16 +0000710 -justify center -aspect 400
711 pack $w.m -side top -fill x -padx 20 -pady 20
712 button $w.ok -text Close -command "destroy $w"
713 pack $w.ok -side bottom
714}
715
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100716proc shortids {ids} {
717 set res {}
718 foreach id $ids {
719 if {[llength $id] > 1} {
720 lappend res [shortids $id]
721 } elseif {[regexp {^[0-9a-f]{40}$} $id]} {
722 lappend res [string range $id 0 7]
723 } else {
724 lappend res $id
725 }
726 }
727 return $res
728}
729
730proc incrange {l x o} {
731 set n [llength $l]
732 while {$x < $n} {
733 set e [lindex $l $x]
734 if {$e ne {}} {
735 lset l $x [expr {$e + $o}]
736 }
737 incr x
738 }
739 return $l
740}
741
742proc ntimes {n o} {
743 set ret {}
744 for {} {$n > 0} {incr n -1} {
745 lappend ret $o
746 }
747 return $ret
748}
749
750proc usedinrange {id l1 l2} {
751 global children commitrow
752
753 if {[info exists commitrow($id)]} {
754 set r $commitrow($id)
755 if {$l1 <= $r && $r <= $l2} {
756 return [expr {$r - $l1 + 1}]
757 }
758 }
759 foreach c $children($id) {
760 if {[info exists commitrow($c)]} {
761 set r $commitrow($c)
762 if {$l1 <= $r && $r <= $l2} {
763 return [expr {$r - $l1 + 1}]
764 }
765 }
766 }
767 return 0
768}
769
770proc sanity {row {full 0}} {
771 global rowidlist rowoffsets
772
773 set col -1
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100774 set ids [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100775 foreach id $ids {
776 incr col
777 if {$id eq {}} continue
778 if {$col < [llength $ids] - 1 &&
779 [lsearch -exact -start [expr {$col+1}] $ids $id] >= 0} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100780 puts "oops: [shortids $id] repeated in row $row col $col: {[shortids [lindex $rowidlist $row]]}"
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100781 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100782 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100783 set y $row
784 set x $col
785 while {$o ne {}} {
786 incr y -1
787 incr x $o
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100788 if {[lindex $rowidlist $y $x] != $id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100789 puts "oops: rowoffsets wrong at row [expr {$y+1}] col [expr {$x-$o}]"
790 puts " id=[shortids $id] check started at row $row"
791 for {set i $row} {$i >= $y} {incr i -1} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100792 puts " row $i ids={[shortids [lindex $rowidlist $i]]} offs={[lindex $rowoffsets $i]}"
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100793 }
794 break
795 }
796 if {!$full} break
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100797 set o [lindex $rowoffsets $y $x]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100798 }
799 }
800}
801
802proc makeuparrow {oid x y z} {
803 global rowidlist rowoffsets uparrowlen idrowranges
804
805 for {set i 1} {$i < $uparrowlen && $y > 1} {incr i} {
806 incr y -1
807 incr x $z
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100808 set off0 [lindex $rowoffsets $y]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100809 for {set x0 $x} {1} {incr x0} {
810 if {$x0 >= [llength $off0]} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100811 set x0 [llength [lindex $rowoffsets [expr {$y-1}]]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100812 break
813 }
814 set z [lindex $off0 $x0]
815 if {$z ne {}} {
816 incr x0 $z
817 break
818 }
819 }
820 set z [expr {$x0 - $x}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100821 lset rowidlist $y [linsert [lindex $rowidlist $y] $x $oid]
822 lset rowoffsets $y [linsert [lindex $rowoffsets $y] $x $z]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100823 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100824 set tmp [lreplace [lindex $rowoffsets $y] $x $x {}]
825 lset rowoffsets $y [incrange $tmp [expr {$x+1}] -1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100826 lappend idrowranges($oid) $y
827}
828
829proc initlayout {} {
830 global rowidlist rowoffsets displayorder
831 global rowlaidout rowoptim
832 global idinlist rowchk
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100833 global commitidx numcommits
834 global nextcolor
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100835
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100836 set commitidx 0
837 set numcommits 0
838 set displayorder {}
839 set nextcolor 0
840 set rowidlist {{}}
841 set rowoffsets {{}}
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100842 catch {unset idinlist}
843 catch {unset rowchk}
844 set rowlaidout 0
845 set rowoptim 0
846}
847
848proc visiblerows {} {
849 global canv numcommits linespc
850
851 set ymax [lindex [$canv cget -scrollregion] 3]
852 if {$ymax eq {} || $ymax == 0} return
853 set f [$canv yview]
854 set y0 [expr {int([lindex $f 0] * $ymax)}]
855 set r0 [expr {int(($y0 - 3) / $linespc) - 1}]
856 if {$r0 < 0} {
857 set r0 0
858 }
859 set y1 [expr {int([lindex $f 1] * $ymax)}]
860 set r1 [expr {int(($y1 - 3) / $linespc) + 1}]
861 if {$r1 >= $numcommits} {
862 set r1 [expr {$numcommits - 1}]
863 }
864 return [list $r0 $r1]
865}
866
867proc layoutmore {} {
868 global rowlaidout rowoptim commitidx numcommits optim_delay
869 global uparrowlen
870
871 set row $rowlaidout
872 set rowlaidout [layoutrows $row $commitidx 0]
873 set orow [expr {$rowlaidout - $uparrowlen - 1}]
874 if {$orow > $rowoptim} {
875 checkcrossings $rowoptim $orow
876 optimize_rows $rowoptim 0 $orow
877 set rowoptim $orow
878 }
879 set canshow [expr {$rowoptim - $optim_delay}]
880 if {$canshow > $numcommits} {
881 showstuff $canshow
882 }
883}
884
885proc showstuff {canshow} {
886 global numcommits
887 global canvy0 linespc
888 global linesegends idrowranges idrangedrawn
889
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100890 if {$numcommits == 0} {
891 global phase
892 set phase "incrdraw"
893 allcanvs delete all
894 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100895 set row $numcommits
896 set numcommits $canshow
897 allcanvs conf -scrollregion \
898 [list 0 0 0 [expr {$canvy0 + ($numcommits - 0.5) * $linespc + 2}]]
899 set rows [visiblerows]
900 set r0 [lindex $rows 0]
901 set r1 [lindex $rows 1]
902 for {set r $row} {$r < $canshow} {incr r} {
903 if {[info exists linesegends($r)]} {
904 foreach id $linesegends($r) {
905 set i -1
906 foreach {s e} $idrowranges($id) {
907 incr i
908 if {$e ne {} && $e < $numcommits && $s <= $r1 && $e >= $r0
909 && ![info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +1100910 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100911 set idrangedrawn($id,$i) 1
912 }
913 }
914 }
915 }
916 }
917 if {$canshow > $r1} {
918 set canshow $r1
919 }
920 while {$row < $canshow} {
921 drawcmitrow $row
922 incr row
923 }
924}
925
926proc layoutrows {row endrow last} {
927 global rowidlist rowoffsets displayorder
928 global uparrowlen downarrowlen maxwidth mingaplen
929 global nchildren parents nparents
930 global idrowranges linesegends
931 global commitidx
932 global idinlist rowchk
933
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100934 set idlist [lindex $rowidlist $row]
935 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100936 while {$row < $endrow} {
937 set id [lindex $displayorder $row]
938 set oldolds {}
939 set newolds {}
940 foreach p $parents($id) {
941 if {![info exists idinlist($p)]} {
942 lappend newolds $p
943 } elseif {!$idinlist($p)} {
944 lappend oldolds $p
945 }
946 }
947 set nev [expr {[llength $idlist] + [llength $newolds]
948 + [llength $oldolds] - $maxwidth + 1}]
949 if {$nev > 0} {
950 if {!$last && $row + $uparrowlen + $mingaplen >= $commitidx} break
951 for {set x [llength $idlist]} {[incr x -1] >= 0} {} {
952 set i [lindex $idlist $x]
953 if {![info exists rowchk($i)] || $row >= $rowchk($i)} {
954 set r [usedinrange $i [expr {$row - $downarrowlen}] \
955 [expr {$row + $uparrowlen + $mingaplen}]]
956 if {$r == 0} {
957 set idlist [lreplace $idlist $x $x]
958 set offs [lreplace $offs $x $x]
959 set offs [incrange $offs $x 1]
960 set idinlist($i) 0
961 lappend linesegends($row) $i
962 lappend idrowranges($i) [expr {$row-1}]
963 if {[incr nev -1] <= 0} break
964 continue
965 }
966 set rowchk($id) [expr {$row + $r}]
967 }
968 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100969 lset rowidlist $row $idlist
970 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100971 }
972 set col [lsearch -exact $idlist $id]
973 if {$col < 0} {
974 set col [llength $idlist]
975 lappend idlist $id
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100976 lset rowidlist $row $idlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100977 set z {}
978 if {$nchildren($id) > 0} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100979 set z [expr {[llength [lindex $rowidlist [expr {$row-1}]]] - $col}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100980 unset idinlist($id)
981 }
982 lappend offs $z
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +1100983 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +1100984 if {$z ne {}} {
985 makeuparrow $id $col $row $z
986 }
987 } else {
988 unset idinlist($id)
989 }
990 if {[info exists idrowranges($id)]} {
991 lappend linesegends($row) $id
992 lappend idrowranges($id) $row
993 }
994 incr row
995 set offs [ntimes [llength $idlist] 0]
996 set l [llength $newolds]
997 set idlist [eval lreplace \$idlist $col $col $newolds]
998 set o 0
999 if {$l != 1} {
1000 set offs [lrange $offs 0 [expr {$col - 1}]]
1001 foreach x $newolds {
1002 lappend offs {}
1003 incr o -1
1004 }
1005 incr o
1006 set tmp [expr {[llength $idlist] - [llength $offs]}]
1007 if {$tmp > 0} {
1008 set offs [concat $offs [ntimes $tmp $o]]
1009 }
1010 } else {
1011 lset offs $col {}
1012 }
1013 foreach i $newolds {
1014 set idinlist($i) 1
1015 set idrowranges($i) $row
1016 }
1017 incr col $l
1018 foreach oid $oldolds {
1019 set idinlist($oid) 1
1020 set idlist [linsert $idlist $col $oid]
1021 set offs [linsert $offs $col $o]
1022 makeuparrow $oid $col $row $o
1023 incr col
1024 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001025 lappend rowidlist $idlist
1026 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001027 }
1028 return $row
1029}
1030
1031proc addextraid {id row} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001032 global displayorder commitrow commitinfo nparents
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001033 global commitidx
1034
1035 incr commitidx
1036 lappend displayorder $id
1037 set commitrow($id) $row
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001038 readcommit $id
1039 if {![info exists commitinfo($id)]} {
1040 set commitinfo($id) {"No commit information available"}
1041 set nparents($id) 0
1042 }
1043}
1044
1045proc layouttail {} {
1046 global rowidlist rowoffsets idinlist commitidx
1047 global idrowranges linesegends
1048
1049 set row $commitidx
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001050 set idlist [lindex $rowidlist $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001051 while {$idlist ne {}} {
1052 set col [expr {[llength $idlist] - 1}]
1053 set id [lindex $idlist $col]
1054 addextraid $id $row
1055 unset idinlist($id)
1056 lappend linesegends($row) $id
1057 lappend idrowranges($id) $row
1058 incr row
1059 set offs [ntimes $col 0]
1060 set idlist [lreplace $idlist $col $col]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001061 lappend rowidlist $idlist
1062 lappend rowoffsets $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001063 }
1064
1065 foreach id [array names idinlist] {
1066 addextraid $id $row
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001067 lset rowidlist $row [list $id]
1068 lset rowoffsets $row 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001069 makeuparrow $id 0 $row 0
1070 lappend linesegends($row) $id
1071 lappend idrowranges($id) $row
1072 incr row
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001073 lappend rowidlist {}
1074 lappend rowoffsets {}
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001075 }
1076}
1077
1078proc insert_pad {row col npad} {
1079 global rowidlist rowoffsets
1080
1081 set pad [ntimes $npad {}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001082 lset rowidlist $row [eval linsert [list [lindex $rowidlist $row]] $col $pad]
1083 set tmp [eval linsert [list [lindex $rowoffsets $row]] $col $pad]
1084 lset rowoffsets $row [incrange $tmp [expr {$col + $npad}] [expr {-$npad}]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001085}
1086
1087proc optimize_rows {row col endrow} {
1088 global rowidlist rowoffsets idrowranges
1089
1090 for {} {$row < $endrow} {incr row} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001091 set idlist [lindex $rowidlist $row]
1092 set offs [lindex $rowoffsets $row]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001093 set haspad 0
1094 for {} {$col < [llength $offs]} {incr col} {
1095 if {[lindex $idlist $col] eq {}} {
1096 set haspad 1
1097 continue
1098 }
1099 set z [lindex $offs $col]
1100 if {$z eq {}} continue
1101 set isarrow 0
1102 set x0 [expr {$col + $z}]
1103 set y0 [expr {$row - 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001104 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001105 if {$z0 eq {}} {
1106 set id [lindex $idlist $col]
1107 if {[info exists idrowranges($id)] &&
1108 $y0 > [lindex $idrowranges($id) 0]} {
1109 set isarrow 1
1110 }
1111 }
1112 if {$z < -1 || ($z < 0 && $isarrow)} {
1113 set npad [expr {-1 - $z + $isarrow}]
1114 set offs [incrange $offs $col $npad]
1115 insert_pad $y0 $x0 $npad
1116 if {$y0 > 0} {
1117 optimize_rows $y0 $x0 $row
1118 }
1119 set z [lindex $offs $col]
1120 set x0 [expr {$col + $z}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001121 set z0 [lindex $rowoffsets $y0 $x0]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001122 } elseif {$z > 1 || ($z > 0 && $isarrow)} {
1123 set npad [expr {$z - 1 + $isarrow}]
1124 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001125 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001126 set x1 -1
1127 foreach z $offs2 {
1128 incr x1
1129 if {$z eq {} || $x1 + $z < $col} continue
1130 if {$x1 + $z > $col} {
1131 incr npad
1132 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001133 lset rowoffsets $y1 [incrange $offs2 $x1 $npad]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001134 break
1135 }
1136 set pad [ntimes $npad {}]
1137 set idlist [eval linsert \$idlist $col $pad]
1138 set tmp [eval linsert \$offs $col $pad]
1139 incr col $npad
1140 set offs [incrange $tmp $col [expr {-$npad}]]
1141 set z [lindex $offs $col]
1142 set haspad 1
1143 }
1144 if {$z0 ne {} && $z < 0 && $z0 > 0} {
1145 insert_pad $y0 $x0 1
1146 set offs [incrange $offs $col 1]
1147 optimize_rows $y0 [expr {$x0 + 1}] $row
1148 }
1149 }
1150 if {!$haspad} {
1151 for {set col [llength $idlist]} {[incr col -1] >= 0} {} {
1152 set o [lindex $offs $col]
1153 if {$o eq {} || $o <= 0} break
1154 }
1155 if {[incr col] < [llength $idlist]} {
1156 set y1 [expr {$row + 1}]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001157 set offs2 [lindex $rowoffsets $y1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001158 set x1 -1
1159 foreach z $offs2 {
1160 incr x1
1161 if {$z eq {} || $x1 + $z < $col} continue
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001162 lset rowoffsets $y1 [incrange $offs2 $x1 1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001163 break
1164 }
1165 set idlist [linsert $idlist $col {}]
1166 set tmp [linsert $offs $col {}]
1167 incr col
1168 set offs [incrange $tmp $col -1]
1169 }
1170 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001171 lset rowidlist $row $idlist
1172 lset rowoffsets $row $offs
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001173 set col 0
1174 }
1175}
1176
1177proc xc {row col} {
1178 global canvx0 linespc
1179 return [expr {$canvx0 + $col * $linespc}]
1180}
1181
1182proc yc {row} {
1183 global canvy0 linespc
1184 return [expr {$canvy0 + $row * $linespc}]
1185}
1186
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001187proc linewidth {id} {
1188 global thickerline lthickness
1189
1190 set wid $lthickness
1191 if {[info exists thickerline] && $id eq $thickerline} {
1192 set wid [expr {2 * $lthickness}]
1193 }
1194 return $wid
1195}
1196
1197proc drawlineseg {id i} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001198 global rowoffsets rowidlist idrowranges
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001199 global canv colormap
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001200
1201 set startrow [lindex $idrowranges($id) [expr {2 * $i}]]
1202 set row [lindex $idrowranges($id) [expr {2 * $i + 1}]]
1203 if {$startrow == $row} return
1204 assigncolor $id
1205 set coords {}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001206 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001207 if {$col < 0} {
1208 puts "oops: drawline: id $id not on row $row"
1209 return
1210 }
1211 set lasto {}
1212 set ns 0
1213 while {1} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001214 set o [lindex $rowoffsets $row $col]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001215 if {$o eq {}} break
1216 if {$o ne $lasto} {
1217 # changing direction
1218 set x [xc $row $col]
1219 set y [yc $row]
1220 lappend coords $x $y
1221 set lasto $o
1222 }
1223 incr col $o
1224 incr row -1
1225 }
1226 if {$coords eq {}} return
1227 set last [expr {[llength $idrowranges($id)] / 2 - 1}]
1228 set arrow [expr {2 * ($i > 0) + ($i < $last)}]
1229 set arrow [lindex {none first last both} $arrow]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001230 set x [xc $row $col]
1231 set y [yc $row]
1232 lappend coords $x $y
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001233 set t [$canv create line $coords -width [linewidth $id] \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001234 -fill $colormap($id) -tags lines.$id -arrow $arrow]
1235 $canv lower $t
1236 bindline $t $id
1237}
1238
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001239proc drawparentlinks {id row col olds} {
1240 global rowidlist canv colormap
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001241
1242 set row2 [expr {$row + 1}]
1243 set x [xc $row $col]
1244 set y [yc $row]
1245 set y2 [yc $row2]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001246 set ids [lindex $rowidlist $row2]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001247 # rmx = right-most X coord used
1248 set rmx 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001249 foreach p $olds {
1250 set i [lsearch -exact $ids $p]
1251 if {$i < 0} {
1252 puts "oops, parent $p of $id not in list"
1253 continue
1254 }
1255 assigncolor $p
1256 # should handle duplicated parents here...
1257 set coords [list $x $y]
1258 if {$i < $col - 1} {
1259 lappend coords [xc $row [expr {$i + 1}]] $y
1260 } elseif {$i > $col + 1} {
1261 lappend coords [xc $row [expr {$i - 1}]] $y
1262 }
1263 set x2 [xc $row2 $i]
1264 if {$x2 > $rmx} {
1265 set rmx $x2
1266 }
1267 lappend coords $x2 $y2
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001268 set t [$canv create line $coords -width [linewidth $p] \
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001269 -fill $colormap($p) -tags lines.$p]
1270 $canv lower $t
1271 bindline $t $p
1272 }
1273 return $rmx
1274}
1275
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001276proc drawlines {id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001277 global colormap canv
1278 global idrowranges idrangedrawn
1279 global children iddrawn commitrow rowidlist
1280
1281 $canv delete lines.$id
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001282 set nr [expr {[llength $idrowranges($id)] / 2}]
1283 for {set i 0} {$i < $nr} {incr i} {
1284 if {[info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001285 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001286 }
1287 }
1288 if {[info exists children($id)]} {
1289 foreach child $children($id) {
1290 if {[info exists iddrawn($child)]} {
1291 set row $commitrow($child)
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001292 set col [lsearch -exact [lindex $rowidlist $row] $child]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001293 if {$col >= 0} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001294 drawparentlinks $child $row $col [list $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001295 }
1296 }
1297 }
1298 }
1299}
1300
1301proc drawcmittext {id row col rmx} {
1302 global linespc canv canv2 canv3 canvy0
1303 global commitlisted commitinfo rowidlist
1304 global rowtextx idpos idtags idheads idotherrefs
1305 global linehtag linentag linedtag
1306 global mainfont namefont
1307
1308 set ofill [expr {[info exists commitlisted($id)]? "blue": "white"}]
1309 set x [xc $row $col]
1310 set y [yc $row]
1311 set orad [expr {$linespc / 3}]
1312 set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
1313 [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
1314 -fill $ofill -outline black -width 1]
1315 $canv raise $t
1316 $canv bind $t <1> {selcanvline {} %x %y}
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001317 set xt [xc $row [llength [lindex $rowidlist $row]]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001318 if {$xt < $rmx} {
1319 set xt $rmx
1320 }
1321 set rowtextx($row) $xt
1322 set idpos($id) [list $x $xt $y]
1323 if {[info exists idtags($id)] || [info exists idheads($id)]
1324 || [info exists idotherrefs($id)]} {
1325 set xt [drawtags $id $x $xt $y]
1326 }
1327 set headline [lindex $commitinfo($id) 0]
1328 set name [lindex $commitinfo($id) 1]
1329 set date [lindex $commitinfo($id) 2]
1330 set date [formatdate $date]
1331 set linehtag($row) [$canv create text $xt $y -anchor w \
1332 -text $headline -font $mainfont ]
1333 $canv bind $linehtag($row) <Button-3> "rowmenu %X %Y $id"
1334 set linentag($row) [$canv2 create text 3 $y -anchor w \
1335 -text $name -font $namefont]
1336 set linedtag($row) [$canv3 create text 3 $y -anchor w \
1337 -text $date -font $mainfont]
1338}
1339
1340proc drawcmitrow {row} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001341 global displayorder rowidlist
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001342 global idrowranges idrangedrawn iddrawn
1343 global commitinfo commitlisted parents numcommits
Paul Mackerras8ed16482006-03-02 22:56:44 +11001344 global commitdata
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001345
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001346 if {$row >= $numcommits} return
1347 foreach id [lindex $rowidlist $row] {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001348 if {![info exists idrowranges($id)]} continue
1349 set i -1
1350 foreach {s e} $idrowranges($id) {
1351 incr i
1352 if {$row < $s} continue
1353 if {$e eq {}} break
1354 if {$row <= $e} {
1355 if {$e < $numcommits && ![info exists idrangedrawn($id,$i)]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001356 drawlineseg $id $i
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001357 set idrangedrawn($id,$i) 1
1358 }
1359 break
1360 }
1361 }
1362 }
1363
1364 set id [lindex $displayorder $row]
1365 if {[info exists iddrawn($id)]} return
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001366 set col [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001367 if {$col < 0} {
1368 puts "oops, row $row id $id not in list"
1369 return
1370 }
1371 if {![info exists commitinfo($id)]} {
Paul Mackerras8ed16482006-03-02 22:56:44 +11001372 getcommit $id $row
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001373 }
1374 assigncolor $id
1375 if {[info exists commitlisted($id)] && [info exists parents($id)]
1376 && $parents($id) ne {}} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11001377 set rmx [drawparentlinks $id $row $col $parents($id)]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001378 } else {
1379 set rmx 0
1380 }
1381 drawcmittext $id $row $col $rmx
1382 set iddrawn($id) 1
1383}
1384
1385proc drawfrac {f0 f1} {
1386 global numcommits canv
1387 global linespc
1388
1389 set ymax [lindex [$canv cget -scrollregion] 3]
1390 if {$ymax eq {} || $ymax == 0} return
1391 set y0 [expr {int($f0 * $ymax)}]
1392 set row [expr {int(($y0 - 3) / $linespc) - 1}]
1393 if {$row < 0} {
1394 set row 0
1395 }
1396 set y1 [expr {int($f1 * $ymax)}]
1397 set endrow [expr {int(($y1 - 3) / $linespc) + 1}]
1398 if {$endrow >= $numcommits} {
1399 set endrow [expr {$numcommits - 1}]
1400 }
1401 for {} {$row <= $endrow} {incr row} {
1402 drawcmitrow $row
1403 }
1404}
1405
1406proc drawvisible {} {
1407 global canv
1408 eval drawfrac [$canv yview]
1409}
1410
1411proc clear_display {} {
1412 global iddrawn idrangedrawn
1413
1414 allcanvs delete all
1415 catch {unset iddrawn}
1416 catch {unset idrangedrawn}
1417}
1418
Paul Mackerrase5c2d852005-05-11 23:44:54 +00001419proc assigncolor {id} {
Paul Mackerrasaa81d972006-02-28 11:27:12 +11001420 global colormap colors nextcolor
Paul Mackerrase5c2d852005-05-11 23:44:54 +00001421 global parents nparents children nchildren
Paul Mackerras6c20ff32005-06-22 19:53:32 +10001422 global cornercrossings crossings
1423
Paul Mackerras418c4c72006-02-07 09:10:18 +11001424 if {[info exists colormap($id)]} return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00001425 set ncolors [llength $colors]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001426 if {$nchildren($id) == 1} {
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001427 set child [lindex $children($id) 0]
1428 if {[info exists colormap($child)]
1429 && $nparents($child) == 1} {
1430 set colormap($id) $colormap($child)
1431 return
Paul Mackerrase5c2d852005-05-11 23:44:54 +00001432 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001433 }
1434 set badcolors {}
Paul Mackerras6c20ff32005-06-22 19:53:32 +10001435 if {[info exists cornercrossings($id)]} {
1436 foreach x $cornercrossings($id) {
1437 if {[info exists colormap($x)]
1438 && [lsearch -exact $badcolors $colormap($x)] < 0} {
1439 lappend badcolors $colormap($x)
1440 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00001441 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10001442 if {[llength $badcolors] >= $ncolors} {
1443 set badcolors {}
1444 }
1445 }
1446 set origbad $badcolors
1447 if {[llength $badcolors] < $ncolors - 1} {
1448 if {[info exists crossings($id)]} {
1449 foreach x $crossings($id) {
1450 if {[info exists colormap($x)]
1451 && [lsearch -exact $badcolors $colormap($x)] < 0} {
1452 lappend badcolors $colormap($x)
1453 }
1454 }
1455 if {[llength $badcolors] >= $ncolors} {
1456 set badcolors $origbad
1457 }
1458 }
1459 set origbad $badcolors
1460 }
1461 if {[llength $badcolors] < $ncolors - 1} {
1462 foreach child $children($id) {
1463 if {[info exists colormap($child)]
1464 && [lsearch -exact $badcolors $colormap($child)] < 0} {
1465 lappend badcolors $colormap($child)
1466 }
1467 if {[info exists parents($child)]} {
1468 foreach p $parents($child) {
1469 if {[info exists colormap($p)]
1470 && [lsearch -exact $badcolors $colormap($p)] < 0} {
1471 lappend badcolors $colormap($p)
1472 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00001473 }
1474 }
1475 }
Paul Mackerras6c20ff32005-06-22 19:53:32 +10001476 if {[llength $badcolors] >= $ncolors} {
1477 set badcolors $origbad
1478 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001479 }
1480 for {set i 0} {$i <= $ncolors} {incr i} {
1481 set c [lindex $colors $nextcolor]
1482 if {[incr nextcolor] >= $ncolors} {
1483 set nextcolor 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00001484 }
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001485 if {[lsearch -exact $badcolors $c]} break
1486 }
1487 set colormap($id) $c
1488}
1489
Paul Mackerrasa823a912005-06-21 10:01:38 +10001490proc bindline {t id} {
1491 global canv
1492
Paul Mackerrasa823a912005-06-21 10:01:38 +10001493 $canv bind $t <Enter> "lineenter %x %y $id"
1494 $canv bind $t <Motion> "linemotion %x %y $id"
1495 $canv bind $t <Leave> "lineleave $id"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10001496 $canv bind $t <Button-1> "lineclick %x %y $id 1"
Paul Mackerrasa823a912005-06-21 10:01:38 +10001497}
1498
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001499proc drawtags {id x xt y1} {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10001500 global idtags idheads idotherrefs
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001501 global linespc lthickness
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001502 global canv mainfont commitrow rowtextx
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001503
1504 set marks {}
1505 set ntags 0
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10001506 set nheads 0
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001507 if {[info exists idtags($id)]} {
1508 set marks $idtags($id)
1509 set ntags [llength $marks]
1510 }
1511 if {[info exists idheads($id)]} {
1512 set marks [concat $marks $idheads($id)]
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10001513 set nheads [llength $idheads($id)]
1514 }
1515 if {[info exists idotherrefs($id)]} {
1516 set marks [concat $marks $idotherrefs($id)]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001517 }
1518 if {$marks eq {}} {
1519 return $xt
1520 }
1521
1522 set delta [expr {int(0.5 * ($linespc - $lthickness))}]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001523 set yt [expr {$y1 - 0.5 * $linespc}]
1524 set yb [expr {$yt + $linespc - 1}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001525 set xvals {}
1526 set wvals {}
1527 foreach tag $marks {
1528 set wid [font measure $mainfont $tag]
1529 lappend xvals $xt
1530 lappend wvals $wid
1531 set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}]
1532 }
1533 set t [$canv create line $x $y1 [lindex $xvals end] $y1 \
1534 -width $lthickness -fill black -tags tag.$id]
1535 $canv lower $t
1536 foreach tag $marks x $xvals wid $wvals {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001537 set xl [expr {$x + $delta}]
1538 set xr [expr {$x + $delta + $wid + $lthickness}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001539 if {[incr ntags -1] >= 0} {
1540 # draw a tag
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001541 set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \
1542 $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \
Paul Mackerras106288c2005-08-19 23:11:39 +10001543 -width 1 -outline black -fill yellow -tags tag.$id]
1544 $canv bind $t <1> [list showtag $tag 1]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001545 set rowtextx($commitrow($id)) [expr {$xr + $linespc}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001546 } else {
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10001547 # draw a head or other ref
1548 if {[incr nheads -1] >= 0} {
1549 set col green
1550 } else {
1551 set col "#ddddff"
1552 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001553 set xl [expr {$xl - $delta/2}]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001554 $canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10001555 -width 1 -outline black -fill $col -tags tag.$id
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001556 }
Paul Mackerras106288c2005-08-19 23:11:39 +10001557 set t [$canv create text $xl $y1 -anchor w -text $tag \
1558 -font $mainfont -tags tag.$id]
1559 if {$ntags >= 0} {
1560 $canv bind $t <1> [list showtag $tag 1]
1561 }
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10001562 }
1563 return $xt
1564}
1565
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001566proc checkcrossings {row endrow} {
1567 global displayorder parents rowidlist
1568
1569 for {} {$row < $endrow} {incr row} {
1570 set id [lindex $displayorder $row]
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001571 set i [lsearch -exact [lindex $rowidlist $row] $id]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001572 if {$i < 0} continue
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001573 set idlist [lindex $rowidlist [expr {$row+1}]]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001574 foreach p $parents($id) {
1575 set j [lsearch -exact $idlist $p]
1576 if {$j > 0} {
1577 if {$j < $i - 1} {
1578 notecrossings $row $p $j $i [expr {$j+1}]
1579 } elseif {$j > $i + 1} {
1580 notecrossings $row $p $i $j [expr {$j-1}]
1581 }
1582 }
1583 }
1584 }
1585}
1586
1587proc notecrossings {row id lo hi corner} {
1588 global rowidlist crossings cornercrossings
Paul Mackerras6c20ff32005-06-22 19:53:32 +10001589
1590 for {set i $lo} {[incr i] < $hi} {} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001591 set p [lindex [lindex $rowidlist $row] $i]
Paul Mackerras6c20ff32005-06-22 19:53:32 +10001592 if {$p == {}} continue
1593 if {$i == $corner} {
1594 if {![info exists cornercrossings($id)]
1595 || [lsearch -exact $cornercrossings($id) $p] < 0} {
1596 lappend cornercrossings($id) $p
1597 }
1598 if {![info exists cornercrossings($p)]
1599 || [lsearch -exact $cornercrossings($p) $id] < 0} {
1600 lappend cornercrossings($p) $id
1601 }
1602 } else {
1603 if {![info exists crossings($id)]
1604 || [lsearch -exact $crossings($id) $p] < 0} {
1605 lappend crossings($id) $p
1606 }
1607 if {![info exists crossings($p)]
1608 || [lsearch -exact $crossings($p) $id] < 0} {
1609 lappend crossings($p) $id
1610 }
1611 }
1612 }
1613}
1614
Paul Mackerras8d858d12005-08-05 09:52:16 +10001615proc xcoord {i level ln} {
1616 global canvx0 xspc1 xspc2
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001617
Paul Mackerras8d858d12005-08-05 09:52:16 +10001618 set x [expr {$canvx0 + $i * $xspc1($ln)}]
1619 if {$i > 0 && $i == $level} {
1620 set x [expr {$x + 0.5 * ($xspc2 - $xspc1($ln))}]
1621 } elseif {$i > $level} {
1622 set x [expr {$x + $xspc2 - $xspc1($ln)}]
1623 }
1624 return $x
1625}
1626
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001627proc finishcommits {} {
Paul Mackerras8ed16482006-03-02 22:56:44 +11001628 global commitidx phase
Paul Mackerras8a0a74a2005-06-27 13:38:29 +10001629 global canv mainfont ctext maincursor textcursor
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001630
Paul Mackerras8ed16482006-03-02 22:56:44 +11001631 if {$commitidx > 0} {
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01001632 drawrest
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01001633 } else {
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001634 $canv delete all
1635 $canv create text 3 3 -anchor nw -text "No commits selected" \
1636 -font $mainfont -tags textitems
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001637 }
Paul Mackerrasea13cba2005-06-16 10:54:04 +00001638 . config -cursor $maincursor
Paul Mackerras94a2eed2005-08-07 15:27:57 +10001639 settextcursor $textcursor
Paul Mackerras8ed16482006-03-02 22:56:44 +11001640 set phase {}
Paul Mackerras94a2eed2005-08-07 15:27:57 +10001641}
1642
1643# Don't change the text pane cursor if it is currently the hand cursor,
1644# showing that we are over a sha1 ID link.
1645proc settextcursor {c} {
1646 global ctext curtextcursor
1647
1648 if {[$ctext cget -cursor] == $curtextcursor} {
1649 $ctext config -cursor $c
1650 }
1651 set curtextcursor $c
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001652}
1653
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10001654proc drawrest {} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001655 global numcommits
1656 global startmsecs
1657 global canvy0 numcommits linespc
1658 global rowlaidout commitidx
Paul Mackerras9ccbdfb2005-06-16 00:27:23 +00001659
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001660 set row $rowlaidout
1661 layoutrows $rowlaidout $commitidx 1
1662 layouttail
1663 optimize_rows $row 0 $commitidx
1664 showstuff $commitidx
Paul Mackerras4dd5d0d2005-12-06 09:46:23 +11001665
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001666 set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}]
Paul Mackerras84ba7342005-06-17 00:12:26 +00001667 #puts "overall $drawmsecs ms for $numcommits commits"
Paul Mackerras1db95b02005-05-09 04:08:39 +00001668}
1669
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001670proc findmatches {f} {
1671 global findtype foundstring foundstrlen
1672 if {$findtype == "Regexp"} {
1673 set matches [regexp -indices -all -inline $foundstring $f]
1674 } else {
1675 if {$findtype == "IgnCase"} {
1676 set str [string tolower $f]
1677 } else {
1678 set str $f
1679 }
1680 set matches {}
1681 set i 0
1682 while {[set j [string first $foundstring $str $i]] >= 0} {
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001683 lappend matches [list $j [expr {$j+$foundstrlen-1}]]
1684 set i [expr {$j + $foundstrlen}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001685 }
1686 }
1687 return $matches
1688}
1689
Paul Mackerras98f350e2005-05-15 05:56:51 +00001690proc dofind {} {
1691 global findtype findloc findstring markedmatches commitinfo
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001692 global numcommits displayorder linehtag linentag linedtag
Paul Mackerras98f350e2005-05-15 05:56:51 +00001693 global mainfont namefont canv canv2 canv3 selectedline
Paul Mackerras8ed16482006-03-02 22:56:44 +11001694 global matchinglines foundstring foundstrlen matchstring
1695 global commitdata
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001696
1697 stopfindproc
Paul Mackerras98f350e2005-05-15 05:56:51 +00001698 unmarkmatches
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001699 focus .
Paul Mackerras98f350e2005-05-15 05:56:51 +00001700 set matchinglines {}
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001701 if {$findloc == "Pickaxe"} {
1702 findpatches
1703 return
1704 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00001705 if {$findtype == "IgnCase"} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001706 set foundstring [string tolower $findstring]
Paul Mackerras98f350e2005-05-15 05:56:51 +00001707 } else {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001708 set foundstring $findstring
Paul Mackerras98f350e2005-05-15 05:56:51 +00001709 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001710 set foundstrlen [string length $findstring]
1711 if {$foundstrlen == 0} return
Paul Mackerras8ed16482006-03-02 22:56:44 +11001712 regsub -all {[*?\[\\]} $foundstring {\\&} matchstring
1713 set matchstring "*$matchstring*"
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001714 if {$findloc == "Files"} {
1715 findfiles
1716 return
1717 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00001718 if {![info exists selectedline]} {
1719 set oldsel -1
1720 } else {
1721 set oldsel $selectedline
1722 }
1723 set didsel 0
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001724 set fldtypes {Headline Author Date Committer CDate Comment}
Paul Mackerras8ed16482006-03-02 22:56:44 +11001725 set l -1
1726 foreach d $commitdata {
1727 incr l
1728 if {$findtype == "Regexp"} {
1729 set doesmatch [regexp $foundstring $d]
1730 } elseif {$findtype == "IgnCase"} {
1731 set doesmatch [string match -nocase $matchstring $d]
1732 } else {
1733 set doesmatch [string match $matchstring $d]
1734 }
1735 if {!$doesmatch} continue
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001736 set id [lindex $displayorder $l]
Paul Mackerras8ed16482006-03-02 22:56:44 +11001737 if {![info exists commitinfo($id)]} {
1738 getcommit $id $l
1739 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00001740 set info $commitinfo($id)
1741 set doesmatch 0
1742 foreach f $info ty $fldtypes {
1743 if {$findloc != "All fields" && $findloc != $ty} {
1744 continue
1745 }
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001746 set matches [findmatches $f]
Paul Mackerras98f350e2005-05-15 05:56:51 +00001747 if {$matches == {}} continue
1748 set doesmatch 1
1749 if {$ty == "Headline"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001750 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00001751 markmatches $canv $l $f $linehtag($l) $matches $mainfont
1752 } elseif {$ty == "Author"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001753 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00001754 markmatches $canv2 $l $f $linentag($l) $matches $namefont
1755 } elseif {$ty == "Date"} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001756 drawcmitrow $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00001757 markmatches $canv3 $l $f $linedtag($l) $matches $mainfont
1758 }
1759 }
1760 if {$doesmatch} {
1761 lappend matchinglines $l
1762 if {!$didsel && $l > $oldsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001763 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00001764 set didsel 1
1765 }
1766 }
1767 }
1768 if {$matchinglines == {}} {
1769 bell
1770 } elseif {!$didsel} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001771 findselectline [lindex $matchinglines 0]
1772 }
1773}
1774
1775proc findselectline {l} {
1776 global findloc commentend ctext
Paul Mackerrasd6982062005-08-06 22:06:06 +10001777 selectline $l 1
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001778 if {$findloc == "All fields" || $findloc == "Comments"} {
1779 # highlight the matches in the comments
1780 set f [$ctext get 1.0 $commentend]
1781 set matches [findmatches $f]
1782 foreach match $matches {
1783 set start [lindex $match 0]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08001784 set end [expr {[lindex $match 1] + 1}]
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001785 $ctext tag add found "1.0 + $start c" "1.0 + $end c"
1786 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00001787 }
1788}
1789
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001790proc findnext {restart} {
Paul Mackerras98f350e2005-05-15 05:56:51 +00001791 global matchinglines selectedline
1792 if {![info exists matchinglines]} {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001793 if {$restart} {
1794 dofind
1795 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00001796 return
1797 }
1798 if {![info exists selectedline]} return
1799 foreach l $matchinglines {
1800 if {$l > $selectedline} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001801 findselectline $l
Paul Mackerras98f350e2005-05-15 05:56:51 +00001802 return
1803 }
1804 }
1805 bell
1806}
1807
1808proc findprev {} {
1809 global matchinglines selectedline
1810 if {![info exists matchinglines]} {
1811 dofind
1812 return
1813 }
1814 if {![info exists selectedline]} return
1815 set prev {}
1816 foreach l $matchinglines {
1817 if {$l >= $selectedline} break
1818 set prev $l
1819 }
1820 if {$prev != {}} {
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00001821 findselectline $prev
Paul Mackerras98f350e2005-05-15 05:56:51 +00001822 } else {
1823 bell
1824 }
1825}
1826
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001827proc findlocchange {name ix op} {
1828 global findloc findtype findtypemenu
1829 if {$findloc == "Pickaxe"} {
1830 set findtype Exact
1831 set state disabled
1832 } else {
1833 set state normal
1834 }
1835 $findtypemenu entryconf 1 -state $state
1836 $findtypemenu entryconf 2 -state $state
1837}
1838
1839proc stopfindproc {{done 0}} {
1840 global findprocpid findprocfile findids
1841 global ctext findoldcursor phase maincursor textcursor
1842 global findinprogress
1843
1844 catch {unset findids}
1845 if {[info exists findprocpid]} {
1846 if {!$done} {
1847 catch {exec kill $findprocpid}
1848 }
1849 catch {close $findprocfile}
1850 unset findprocpid
1851 }
1852 if {[info exists findinprogress]} {
1853 unset findinprogress
1854 if {$phase != "incrdraw"} {
1855 . config -cursor $maincursor
Paul Mackerras94a2eed2005-08-07 15:27:57 +10001856 settextcursor $textcursor
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001857 }
1858 }
1859}
1860
1861proc findpatches {} {
1862 global findstring selectedline numcommits
1863 global findprocpid findprocfile
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001864 global finddidsel ctext displayorder findinprogress
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04001865 global findinsertpos
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001866
1867 if {$numcommits == 0} return
1868
1869 # make a list of all the ids to search, starting at the one
1870 # after the selected line (if any)
1871 if {[info exists selectedline]} {
1872 set l $selectedline
1873 } else {
1874 set l -1
1875 }
1876 set inputids {}
1877 for {set i 0} {$i < $numcommits} {incr i} {
1878 if {[incr l] >= $numcommits} {
1879 set l 0
1880 }
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001881 append inputids [lindex $displayorder $l] "\n"
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001882 }
1883
1884 if {[catch {
1885 set f [open [list | git-diff-tree --stdin -s -r -S$findstring \
1886 << $inputids] r]
1887 } err]} {
1888 error_popup "Error starting search process: $err"
1889 return
1890 }
1891
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04001892 set findinsertpos end
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001893 set findprocfile $f
1894 set findprocpid [pid $f]
1895 fconfigure $f -blocking 0
1896 fileevent $f readable readfindproc
1897 set finddidsel 0
1898 . config -cursor watch
Paul Mackerras94a2eed2005-08-07 15:27:57 +10001899 settextcursor watch
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001900 set findinprogress 1
1901}
1902
1903proc readfindproc {} {
1904 global findprocfile finddidsel
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001905 global commitrow matchinglines findinsertpos
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001906
1907 set n [gets $findprocfile line]
1908 if {$n < 0} {
1909 if {[eof $findprocfile]} {
1910 stopfindproc 1
1911 if {!$finddidsel} {
1912 bell
1913 }
1914 }
1915 return
1916 }
1917 if {![regexp {^[0-9a-f]{40}} $line id]} {
1918 error_popup "Can't parse git-diff-tree output: $line"
1919 stopfindproc
1920 return
1921 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001922 if {![info exists commitrow($id)]} {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001923 puts stderr "spurious id: $id"
1924 return
1925 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11001926 set l $commitrow($id)
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04001927 insertmatch $l $id
1928}
1929
1930proc insertmatch {l id} {
1931 global matchinglines findinsertpos finddidsel
1932
1933 if {$findinsertpos == "end"} {
1934 if {$matchinglines != {} && $l < [lindex $matchinglines 0]} {
1935 set matchinglines [linsert $matchinglines 0 $l]
1936 set findinsertpos 1
1937 } else {
1938 lappend matchinglines $l
1939 }
1940 } else {
1941 set matchinglines [linsert $matchinglines $findinsertpos $l]
1942 incr findinsertpos
1943 }
1944 markheadline $l $id
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001945 if {!$finddidsel} {
1946 findselectline $l
1947 set finddidsel 1
1948 }
1949}
1950
1951proc findfiles {} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001952 global selectedline numcommits displayorder ctext
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04001953 global ffileline finddidsel parents nparents
1954 global findinprogress findstartline findinsertpos
Paul Mackerras69d47bd2006-02-10 10:29:26 +11001955 global treediffs fdiffid fdiffsneeded fdiffpos
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04001956 global findmergefiles
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001957
1958 if {$numcommits == 0} return
1959
1960 if {[info exists selectedline]} {
1961 set l [expr {$selectedline + 1}]
1962 } else {
1963 set l 0
1964 }
1965 set ffileline $l
Paul Mackerrasb74fd572005-07-16 07:46:13 -04001966 set findstartline $l
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04001967 set diffsneeded {}
1968 set fdiffsneeded {}
1969 while 1 {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001970 set id [lindex $displayorder $l]
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04001971 if {$findmergefiles || $nparents($id) == 1} {
Paul Mackerras69d47bd2006-02-10 10:29:26 +11001972 if {![info exists treediffs($id)]} {
1973 append diffsneeded "$id\n"
1974 lappend fdiffsneeded $id
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04001975 }
1976 }
1977 if {[incr l] >= $numcommits} {
1978 set l 0
1979 }
1980 if {$l == $findstartline} break
1981 }
1982
1983 # start off a git-diff-tree process if needed
1984 if {$diffsneeded ne {}} {
1985 if {[catch {
1986 set df [open [list | git-diff-tree -r --stdin << $diffsneeded] r]
1987 } err ]} {
1988 error_popup "Error starting search process: $err"
1989 return
1990 }
Paul Mackerras69d47bd2006-02-10 10:29:26 +11001991 catch {unset fdiffid}
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04001992 set fdiffpos 0
1993 fconfigure $df -blocking 0
1994 fileevent $df readable [list readfilediffs $df]
1995 }
1996
1997 set finddidsel 0
1998 set findinsertpos end
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11001999 set id [lindex $displayorder $l]
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002000 . config -cursor watch
Paul Mackerras94a2eed2005-08-07 15:27:57 +10002001 settextcursor watch
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002002 set findinprogress 1
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002003 findcont $id
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002004 update
2005}
2006
2007proc readfilediffs {df} {
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002008 global findid fdiffid fdiffs
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002009
2010 set n [gets $df line]
2011 if {$n < 0} {
2012 if {[eof $df]} {
2013 donefilediff
2014 if {[catch {close $df} err]} {
2015 stopfindproc
2016 bell
2017 error_popup "Error in git-diff-tree: $err"
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002018 } elseif {[info exists findid]} {
2019 set id $findid
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002020 stopfindproc
2021 bell
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002022 error_popup "Couldn't find diffs for $id"
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002023 }
2024 }
2025 return
2026 }
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002027 if {[regexp {^([0-9a-f]{40})$} $line match id]} {
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002028 # start of a new string of diffs
2029 donefilediff
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002030 set fdiffid $id
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002031 set fdiffs {}
2032 } elseif {[string match ":*" $line]} {
2033 lappend fdiffs [lindex $line 5]
2034 }
2035}
2036
2037proc donefilediff {} {
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002038 global fdiffid fdiffs treediffs findid
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002039 global fdiffsneeded fdiffpos
2040
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002041 if {[info exists fdiffid]} {
2042 while {[lindex $fdiffsneeded $fdiffpos] ne $fdiffid
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002043 && $fdiffpos < [llength $fdiffsneeded]} {
2044 # git-diff-tree doesn't output anything for a commit
2045 # which doesn't change anything
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002046 set nullid [lindex $fdiffsneeded $fdiffpos]
2047 set treediffs($nullid) {}
2048 if {[info exists findid] && $nullid eq $findid} {
2049 unset findid
2050 findcont $nullid
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002051 }
2052 incr fdiffpos
2053 }
2054 incr fdiffpos
2055
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002056 if {![info exists treediffs($fdiffid)]} {
2057 set treediffs($fdiffid) $fdiffs
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002058 }
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002059 if {[info exists findid] && $fdiffid eq $findid} {
2060 unset findid
2061 findcont $fdiffid
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002062 }
2063 }
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002064}
2065
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002066proc findcont {id} {
2067 global findid treediffs parents nparents
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002068 global ffileline findstartline finddidsel
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002069 global displayorder numcommits matchinglines findinprogress
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002070 global findmergefiles
2071
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002072 set l $ffileline
2073 while 1 {
2074 if {$findmergefiles || $nparents($id) == 1} {
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002075 if {![info exists treediffs($id)]} {
2076 set findid $id
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002077 set ffileline $l
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002078 return
2079 }
2080 set doesmatch 0
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002081 foreach f $treediffs($id) {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002082 set x [findmatches $f]
2083 if {$x != {}} {
2084 set doesmatch 1
2085 break
2086 }
2087 }
2088 if {$doesmatch} {
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002089 insertmatch $l $id
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002090 }
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002091 }
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002092 if {[incr l] >= $numcommits} {
2093 set l 0
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002094 }
Paul Mackerras69d47bd2006-02-10 10:29:26 +11002095 if {$l == $findstartline} break
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002096 set id [lindex $displayorder $l]
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002097 }
2098 stopfindproc
2099 if {!$finddidsel} {
2100 bell
2101 }
2102}
2103
2104# mark a commit as matching by putting a yellow background
2105# behind the headline
2106proc markheadline {l id} {
Paul Mackerras8ed16482006-03-02 22:56:44 +11002107 global canv mainfont linehtag
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002108
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002109 drawcmitrow $l
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002110 set bbox [$canv bbox $linehtag($l)]
2111 set t [$canv create rect $bbox -outline {} -tags matches -fill yellow]
2112 $canv lower $t
2113}
2114
2115# mark the bits of a headline, author or date that match a find string
Paul Mackerras98f350e2005-05-15 05:56:51 +00002116proc markmatches {canv l str tag matches font} {
2117 set bbox [$canv bbox $tag]
2118 set x0 [lindex $bbox 0]
2119 set y0 [lindex $bbox 1]
2120 set y1 [lindex $bbox 3]
2121 foreach match $matches {
2122 set start [lindex $match 0]
2123 set end [lindex $match 1]
2124 if {$start > $end} continue
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08002125 set xoff [font measure $font [string range $str 0 [expr {$start-1}]]]
2126 set xlen [font measure $font [string range $str 0 [expr {$end}]]]
2127 set t [$canv create rect [expr {$x0+$xoff}] $y0 \
2128 [expr {$x0+$xlen+2}] $y1 \
Paul Mackerras98f350e2005-05-15 05:56:51 +00002129 -outline {} -tags matches -fill yellow]
2130 $canv lower $t
2131 }
2132}
2133
2134proc unmarkmatches {} {
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002135 global matchinglines findids
Paul Mackerras98f350e2005-05-15 05:56:51 +00002136 allcanvs delete matches
2137 catch {unset matchinglines}
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002138 catch {unset findids}
Paul Mackerras98f350e2005-05-15 05:56:51 +00002139}
2140
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002141proc selcanvline {w x y} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002142 global canv canvy0 ctext linespc
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002143 global rowtextx
Paul Mackerras1db95b02005-05-09 04:08:39 +00002144 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerrascfb45632005-05-31 12:14:42 +00002145 if {$ymax == {}} return
Paul Mackerras1db95b02005-05-09 04:08:39 +00002146 set yfrac [lindex [$canv yview] 0]
2147 set y [expr {$y + $yfrac * $ymax}]
2148 set l [expr {int(($y - $canvy0) / $linespc + 0.5)}]
2149 if {$l < 0} {
2150 set l 0
2151 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002152 if {$w eq $canv} {
2153 if {![info exists rowtextx($l)] || $x < $rowtextx($l)} return
2154 }
Paul Mackerras98f350e2005-05-15 05:56:51 +00002155 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10002156 selectline $l 1
Paul Mackerras5ad588d2005-05-10 01:02:55 +00002157}
2158
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07002159proc commit_descriptor {p} {
2160 global commitinfo
2161 set l "..."
2162 if {[info exists commitinfo($p)]} {
2163 set l [lindex $commitinfo($p) 0]
2164 }
2165 return "$p ($l)"
2166}
2167
Paul Mackerras106288c2005-08-19 23:11:39 +10002168# append some text to the ctext widget, and make any SHA1 ID
2169# that we know about be a clickable link.
2170proc appendwithlinks {text} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002171 global ctext commitrow linknum
Paul Mackerras106288c2005-08-19 23:11:39 +10002172
2173 set start [$ctext index "end - 1c"]
2174 $ctext insert end $text
2175 $ctext insert end "\n"
2176 set links [regexp -indices -all -inline {[0-9a-f]{40}} $text]
2177 foreach l $links {
2178 set s [lindex $l 0]
2179 set e [lindex $l 1]
2180 set linkid [string range $text $s $e]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002181 if {![info exists commitrow($linkid)]} continue
Paul Mackerras106288c2005-08-19 23:11:39 +10002182 incr e
2183 $ctext tag add link "$start + $s c" "$start + $e c"
2184 $ctext tag add link$linknum "$start + $s c" "$start + $e c"
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002185 $ctext tag bind link$linknum <1> [list selectline $commitrow($linkid) 1]
Paul Mackerras106288c2005-08-19 23:11:39 +10002186 incr linknum
2187 }
2188 $ctext tag conf link -foreground blue -underline 1
2189 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
2190 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
2191}
2192
Paul Mackerrasd6982062005-08-06 22:06:06 +10002193proc selectline {l isnew} {
Paul Mackerrasd2610d12005-05-11 00:45:38 +00002194 global canv canv2 canv3 ctext commitinfo selectedline
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002195 global displayorder linehtag linentag linedtag
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10002196 global canvy0 linespc parents nparents children
Paul Mackerras14c9dbd2005-07-16 21:53:55 -04002197 global cflist currentid sha1entry
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002198 global commentend idtags linknum
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002199 global mergemax numcommits
Paul Mackerrasd6982062005-08-06 22:06:06 +10002200
Paul Mackerras84ba7342005-06-17 00:12:26 +00002201 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10002202 normalline
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002203 if {$l < 0 || $l >= $numcommits} return
Paul Mackerras5ad588d2005-05-10 01:02:55 +00002204 set y [expr {$canvy0 + $l * $linespc}]
Paul Mackerras17386062005-05-18 22:51:00 +00002205 set ymax [lindex [$canv cget -scrollregion] 3]
Paul Mackerras58422152005-05-19 10:56:42 +00002206 set ytop [expr {$y - $linespc - 1}]
2207 set ybot [expr {$y + $linespc + 1}]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00002208 set wnow [$canv yview]
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08002209 set wtop [expr {[lindex $wnow 0] * $ymax}]
2210 set wbot [expr {[lindex $wnow 1] * $ymax}]
Paul Mackerras58422152005-05-19 10:56:42 +00002211 set wh [expr {$wbot - $wtop}]
2212 set newtop $wtop
Paul Mackerras17386062005-05-18 22:51:00 +00002213 if {$ytop < $wtop} {
Paul Mackerras58422152005-05-19 10:56:42 +00002214 if {$ybot < $wtop} {
2215 set newtop [expr {$y - $wh / 2.0}]
2216 } else {
2217 set newtop $ytop
2218 if {$newtop > $wtop - $linespc} {
2219 set newtop [expr {$wtop - $linespc}]
2220 }
Paul Mackerras17386062005-05-18 22:51:00 +00002221 }
Paul Mackerras58422152005-05-19 10:56:42 +00002222 } elseif {$ybot > $wbot} {
2223 if {$ytop > $wbot} {
2224 set newtop [expr {$y - $wh / 2.0}]
2225 } else {
2226 set newtop [expr {$ybot - $wh}]
2227 if {$newtop < $wtop + $linespc} {
2228 set newtop [expr {$wtop + $linespc}]
2229 }
Paul Mackerras17386062005-05-18 22:51:00 +00002230 }
Paul Mackerras58422152005-05-19 10:56:42 +00002231 }
2232 if {$newtop != $wtop} {
2233 if {$newtop < 0} {
2234 set newtop 0
2235 }
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08002236 allcanvs yview moveto [expr {$newtop * 1.0 / $ymax}]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002237 drawvisible
Paul Mackerras5ad588d2005-05-10 01:02:55 +00002238 }
Paul Mackerrasd6982062005-08-06 22:06:06 +10002239
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002240 if {![info exists linehtag($l)]} return
2241 $canv delete secsel
2242 set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
2243 -tags secsel -fill [$canv cget -selectbackground]]
2244 $canv lower $t
2245 $canv2 delete secsel
2246 set t [eval $canv2 create rect [$canv2 bbox $linentag($l)] -outline {{}} \
2247 -tags secsel -fill [$canv2 cget -selectbackground]]
2248 $canv2 lower $t
2249 $canv3 delete secsel
2250 set t [eval $canv3 create rect [$canv3 bbox $linedtag($l)] -outline {{}} \
2251 -tags secsel -fill [$canv3 cget -selectbackground]]
2252 $canv3 lower $t
2253
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002254 if {$isnew} {
2255 addtohistory [list selectline $l 0]
Paul Mackerrasd6982062005-08-06 22:06:06 +10002256 }
2257
Paul Mackerras5ad588d2005-05-10 01:02:55 +00002258 set selectedline $l
2259
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002260 set id [lindex $displayorder $l]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00002261 set currentid $id
Paul Mackerras98f350e2005-05-15 05:56:51 +00002262 $sha1entry delete 0 end
2263 $sha1entry insert 0 $id
2264 $sha1entry selection from 0
2265 $sha1entry selection to end
Paul Mackerras98f350e2005-05-15 05:56:51 +00002266
Paul Mackerras5ad588d2005-05-10 01:02:55 +00002267 $ctext conf -state normal
Paul Mackerras1db95b02005-05-09 04:08:39 +00002268 $ctext delete 0.0 end
Paul Mackerras106288c2005-08-19 23:11:39 +10002269 set linknum 0
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002270 $ctext mark set fmark.0 0.0
2271 $ctext mark gravity fmark.0 left
Paul Mackerras1db95b02005-05-09 04:08:39 +00002272 set info $commitinfo($id)
Paul Mackerras232475d2005-11-15 10:34:03 +11002273 set date [formatdate [lindex $info 2]]
2274 $ctext insert end "Author: [lindex $info 1] $date\n"
2275 set date [formatdate [lindex $info 4]]
2276 $ctext insert end "Committer: [lindex $info 3] $date\n"
Paul Mackerras887fe3c2005-05-21 07:35:37 +00002277 if {[info exists idtags($id)]} {
2278 $ctext insert end "Tags:"
2279 foreach tag $idtags($id) {
2280 $ctext insert end " $tag"
2281 }
2282 $ctext insert end "\n"
2283 }
Linus Torvalds8b192802005-08-07 13:58:56 -07002284
Linus Torvalds8b192802005-08-07 13:58:56 -07002285 set comment {}
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002286 if {$nparents($id) > 1} {
2287 set np 0
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07002288 foreach p $parents($id) {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002289 if {$np >= $mergemax} {
2290 set tag mmax
2291 } else {
2292 set tag m$np
2293 }
2294 $ctext insert end "Parent: " $tag
2295 appendwithlinks [commit_descriptor $p]
2296 incr np
2297 }
2298 } else {
2299 if {[info exists parents($id)]} {
2300 foreach p $parents($id) {
2301 append comment "Parent: [commit_descriptor $p]\n"
2302 }
Linus Torvalds8b192802005-08-07 13:58:56 -07002303 }
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07002304 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002305
Linus Torvaldsb1ba39e2005-08-08 20:04:20 -07002306 if {[info exists children($id)]} {
2307 foreach c $children($id) {
2308 append comment "Child: [commit_descriptor $c]\n"
2309 }
Linus Torvalds8b192802005-08-07 13:58:56 -07002310 }
2311 append comment "\n"
2312 append comment [lindex $info 5]
Paul Mackerrasd6982062005-08-06 22:06:06 +10002313
2314 # make anything that looks like a SHA1 ID be a clickable link
Paul Mackerras106288c2005-08-19 23:11:39 +10002315 appendwithlinks $comment
Paul Mackerrasd6982062005-08-06 22:06:06 +10002316
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002317 $ctext tag delete Comments
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00002318 $ctext tag remove found 1.0 end
Paul Mackerras5ad588d2005-05-10 01:02:55 +00002319 $ctext conf -state disabled
Paul Mackerrasdf3d83b2005-05-17 23:23:07 +00002320 set commentend [$ctext index "end - 1c"]
Paul Mackerras5ad588d2005-05-10 01:02:55 +00002321
2322 $cflist delete 0 end
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002323 $cflist insert end "Comments"
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002324 if {$nparents($id) == 1} {
Paul Mackerrasd3272442005-11-28 20:41:56 +11002325 startdiff $id
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002326 } elseif {$nparents($id) > 1} {
2327 mergediff $id
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002328 }
2329}
2330
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002331proc selnextline {dir} {
2332 global selectedline
2333 if {![info exists selectedline]} return
Jeff Hobbs2ed49d52005-11-22 17:39:53 -08002334 set l [expr {$selectedline + $dir}]
Paul Mackerras98f350e2005-05-15 05:56:51 +00002335 unmarkmatches
Paul Mackerrasd6982062005-08-06 22:06:06 +10002336 selectline $l 1
2337}
2338
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002339proc unselectline {} {
2340 global selectedline
2341
2342 catch {unset selectedline}
2343 allcanvs delete secsel
2344}
2345
2346proc addtohistory {cmd} {
2347 global history historyindex
2348
2349 if {$historyindex > 0
2350 && [lindex $history [expr {$historyindex - 1}]] == $cmd} {
2351 return
2352 }
2353
2354 if {$historyindex < [llength $history]} {
2355 set history [lreplace $history $historyindex end $cmd]
2356 } else {
2357 lappend history $cmd
2358 }
2359 incr historyindex
2360 if {$historyindex > 1} {
2361 .ctop.top.bar.leftbut conf -state normal
2362 } else {
2363 .ctop.top.bar.leftbut conf -state disabled
2364 }
2365 .ctop.top.bar.rightbut conf -state disabled
2366}
2367
Paul Mackerrasd6982062005-08-06 22:06:06 +10002368proc goback {} {
2369 global history historyindex
2370
2371 if {$historyindex > 1} {
2372 incr historyindex -1
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002373 set cmd [lindex $history [expr {$historyindex - 1}]]
2374 eval $cmd
Paul Mackerrasd6982062005-08-06 22:06:06 +10002375 .ctop.top.bar.rightbut conf -state normal
2376 }
2377 if {$historyindex <= 1} {
2378 .ctop.top.bar.leftbut conf -state disabled
2379 }
2380}
2381
2382proc goforw {} {
2383 global history historyindex
2384
2385 if {$historyindex < [llength $history]} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002386 set cmd [lindex $history $historyindex]
Paul Mackerrasd6982062005-08-06 22:06:06 +10002387 incr historyindex
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002388 eval $cmd
Paul Mackerrasd6982062005-08-06 22:06:06 +10002389 .ctop.top.bar.leftbut conf -state normal
2390 }
2391 if {$historyindex >= [llength $history]} {
2392 .ctop.top.bar.rightbut conf -state disabled
2393 }
Paul Mackerras5ad588d2005-05-10 01:02:55 +00002394}
2395
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002396proc mergediff {id} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002397 global parents diffmergeid diffopts mdifffd
2398 global difffilestart
Paul Mackerrase2ed4322005-07-17 03:39:44 -04002399
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002400 set diffmergeid $id
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002401 catch {unset difffilestart}
2402 # this doesn't seem to actually affect anything...
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002403 set env(GIT_DIFF_OPTS) $diffopts
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002404 set cmd [concat | git-diff-tree --no-commit-id --cc $id]
2405 if {[catch {set mdf [open $cmd r]} err]} {
2406 error_popup "Error getting merge diffs: $err"
2407 return
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002408 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002409 fconfigure $mdf -blocking 0
2410 set mdifffd($id) $mdf
2411 fileevent $mdf readable [list getmergediffline $mdf $id]
2412 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002413}
2414
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002415proc getmergediffline {mdf id} {
2416 global diffmergeid ctext cflist nextupdate nparents mergemax
2417 global difffilestart
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002418
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002419 set n [gets $mdf line]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002420 if {$n < 0} {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002421 if {[eof $mdf]} {
2422 close $mdf
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002423 }
2424 return
2425 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002426 if {![info exists diffmergeid] || $id != $diffmergeid} {
2427 return
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002428 }
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002429 $ctext conf -state normal
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002430 if {[regexp {^diff --cc (.*)} $line match fname]} {
2431 # start of a new file
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002432 $ctext insert end "\n"
2433 set here [$ctext index "end - 1c"]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002434 set i [$cflist index end]
2435 $ctext mark set fmark.$i $here
2436 $ctext mark gravity fmark.$i left
2437 set difffilestart([expr {$i-1}]) $here
2438 $cflist insert end $fname
2439 set l [expr {(78 - [string length $fname]) / 2}]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002440 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002441 $ctext insert end "$pad $fname $pad\n" filesep
2442 } elseif {[regexp {^@@} $line]} {
2443 $ctext insert end "$line\n" hunksep
2444 } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
2445 # do nothing
2446 } else {
2447 # parse the prefix - one ' ', '-' or '+' for each parent
2448 set np $nparents($id)
2449 set spaces {}
2450 set minuses {}
2451 set pluses {}
2452 set isbad 0
2453 for {set j 0} {$j < $np} {incr j} {
2454 set c [string range $line $j $j]
2455 if {$c == " "} {
2456 lappend spaces $j
2457 } elseif {$c == "-"} {
2458 lappend minuses $j
2459 } elseif {$c == "+"} {
2460 lappend pluses $j
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002461 } else {
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002462 set isbad 1
2463 break
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002464 }
2465 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002466 set tags {}
2467 set num {}
2468 if {!$isbad && $minuses ne {} && $pluses eq {}} {
2469 # line doesn't appear in result, parents in $minuses have the line
2470 set num [lindex $minuses 0]
2471 } elseif {!$isbad && $pluses ne {} && $minuses eq {}} {
2472 # line appears in result, parents in $pluses don't have the line
2473 lappend tags mresult
2474 set num [lindex $spaces 0]
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002475 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002476 if {$num ne {}} {
2477 if {$num >= $mergemax} {
2478 set num "max"
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002479 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002480 lappend tags m$num
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002481 }
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002482 $ctext insert end "$line\n" $tags
Paul Mackerras9d2a52e2005-07-27 22:15:47 -05002483 }
2484 $ctext conf -state disabled
Paul Mackerrasb77b0272006-02-07 09:13:52 +11002485 if {[clock clicks -milliseconds] >= $nextupdate} {
2486 incr nextupdate 100
2487 fileevent $mdf readable {}
2488 update
2489 fileevent $mdf readable [list getmergediffline $mdf $id]
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05002490 }
Paul Mackerrasc8a4acb2005-07-29 09:23:03 -05002491}
2492
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002493proc startdiff {ids} {
2494 global treediffs diffids treepending diffmergeid
2495
2496 set diffids $ids
2497 catch {unset diffmergeid}
2498 if {![info exists treediffs($ids)]} {
2499 if {![info exists treepending]} {
2500 gettreediffs $ids
2501 }
2502 } else {
2503 addtocflist $ids
2504 }
2505}
2506
2507proc addtocflist {ids} {
2508 global treediffs cflist
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002509 foreach f $treediffs($ids) {
Paul Mackerrasd2610d12005-05-11 00:45:38 +00002510 $cflist insert end $f
2511 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002512 getblobdiffs $ids
Paul Mackerrasd2610d12005-05-11 00:45:38 +00002513}
2514
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002515proc gettreediffs {ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002516 global treediff parents treepending
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002517 set treepending $ids
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002518 set treediff {}
Paul Mackerras418c4c72006-02-07 09:10:18 +11002519 if {[catch \
2520 {set gdtf [open [concat | git-diff-tree --no-commit-id -r $ids] r]} \
2521 ]} return
Paul Mackerrasd2610d12005-05-11 00:45:38 +00002522 fconfigure $gdtf -blocking 0
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002523 fileevent $gdtf readable [list gettreediffline $gdtf $ids]
Paul Mackerrasd2610d12005-05-11 00:45:38 +00002524}
2525
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002526proc gettreediffline {gdtf ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002527 global treediff treediffs treepending diffids diffmergeid
2528
Paul Mackerrasd2610d12005-05-11 00:45:38 +00002529 set n [gets $gdtf line]
2530 if {$n < 0} {
2531 if {![eof $gdtf]} return
2532 close $gdtf
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002533 set treediffs($ids) $treediff
Paul Mackerrasd2610d12005-05-11 00:45:38 +00002534 unset treepending
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002535 if {$ids != $diffids} {
2536 gettreediffs $diffids
2537 } else {
2538 if {[info exists diffmergeid]} {
2539 contmergediff $ids
Paul Mackerrasb74fd572005-07-16 07:46:13 -04002540 } else {
2541 addtocflist $ids
2542 }
2543 }
Paul Mackerrasd2610d12005-05-11 00:45:38 +00002544 return
2545 }
Paul Mackerrasd4e95cb2005-06-01 00:02:13 +00002546 set file [lindex $line 5]
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002547 lappend treediff $file
Paul Mackerrasd2610d12005-05-11 00:45:38 +00002548}
2549
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002550proc getblobdiffs {ids} {
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002551 global diffopts blobdifffd diffids env curdifftag curtagstart
Paul Mackerras7eab2932005-07-20 12:25:54 -04002552 global difffilestart nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002553
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002554 set env(GIT_DIFF_OPTS) $diffopts
Paul Mackerrasd3272442005-11-28 20:41:56 +11002555 set cmd [concat | git-diff-tree --no-commit-id -r -p -C $ids]
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002556 if {[catch {set bdf [open $cmd r]} err]} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002557 puts "error getting diffs: $err"
2558 return
2559 }
Paul Mackerras4f2c2642005-07-17 11:11:44 -04002560 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002561 fconfigure $bdf -blocking 0
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002562 set blobdifffd($ids) $bdf
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002563 set curdifftag Comments
2564 set curtagstart 0.0
Paul Mackerras3c461ff2005-07-20 09:13:46 -04002565 catch {unset difffilestart}
2566 fileevent $bdf readable [list getblobdiffline $bdf $diffids]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002567 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002568}
2569
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002570proc getblobdiffline {bdf ids} {
Paul Mackerras4f2c2642005-07-17 11:11:44 -04002571 global diffids blobdifffd ctext curdifftag curtagstart
Paul Mackerras7eab2932005-07-20 12:25:54 -04002572 global diffnexthead diffnextnote difffilestart
2573 global nextupdate diffinhdr treediffs
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002574
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002575 set n [gets $bdf line]
2576 if {$n < 0} {
2577 if {[eof $bdf]} {
2578 close $bdf
Paul Mackerrase2ed4322005-07-17 03:39:44 -04002579 if {$ids == $diffids && $bdf == $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002580 $ctext tag add $curdifftag $curtagstart end
2581 }
2582 }
2583 return
2584 }
Paul Mackerrase2ed4322005-07-17 03:39:44 -04002585 if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002586 return
2587 }
2588 $ctext conf -state normal
Paul Mackerras7eab2932005-07-20 12:25:54 -04002589 if {[regexp {^diff --git a/(.*) b/(.*)} $line match fname newname]} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002590 # start of a new file
2591 $ctext insert end "\n"
2592 $ctext tag add $curdifftag $curtagstart end
2593 set curtagstart [$ctext index "end - 1c"]
Paul Mackerras7eab2932005-07-20 12:25:54 -04002594 set header $newname
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002595 set here [$ctext index "end - 1c"]
Paul Mackerras7eab2932005-07-20 12:25:54 -04002596 set i [lsearch -exact $treediffs($diffids) $fname]
2597 if {$i >= 0} {
2598 set difffilestart($i) $here
2599 incr i
2600 $ctext mark set fmark.$i $here
2601 $ctext mark gravity fmark.$i left
2602 }
2603 if {$newname != $fname} {
2604 set i [lsearch -exact $treediffs($diffids) $newname]
2605 if {$i >= 0} {
2606 set difffilestart($i) $here
2607 incr i
2608 $ctext mark set fmark.$i $here
2609 $ctext mark gravity fmark.$i left
2610 }
2611 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002612 set curdifftag "f:$fname"
2613 $ctext tag delete $curdifftag
Paul Mackerras58422152005-05-19 10:56:42 +00002614 set l [expr {(78 - [string length $header]) / 2}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002615 set pad [string range "----------------------------------------" 1 $l]
Paul Mackerras58422152005-05-19 10:56:42 +00002616 $ctext insert end "$pad $header $pad\n" filesep
Paul Mackerras4f2c2642005-07-17 11:11:44 -04002617 set diffinhdr 1
Paul Mackerrasb06bc2a2006-03-08 09:15:32 +11002618 } elseif {$diffinhdr && [string compare -length 3 $line "---"] == 0} {
2619 # do nothing
2620 } elseif {$diffinhdr && [string compare -length 3 $line "+++"] == 0} {
Paul Mackerras4f2c2642005-07-17 11:11:44 -04002621 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002622 } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
2623 $line match f1l f1c f2l f2c rest]} {
Paul Mackerras712fcc02005-11-30 09:28:16 +11002624 $ctext insert end "$line\n" hunksep
Paul Mackerras4f2c2642005-07-17 11:11:44 -04002625 set diffinhdr 0
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002626 } else {
2627 set x [string range $line 0 0]
2628 if {$x == "-" || $x == "+"} {
2629 set tag [expr {$x == "+"}]
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002630 $ctext insert end "$line\n" d$tag
2631 } elseif {$x == " "} {
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002632 $ctext insert end "$line\n"
Paul Mackerras4f2c2642005-07-17 11:11:44 -04002633 } elseif {$diffinhdr || $x == "\\"} {
Paul Mackerras58422152005-05-19 10:56:42 +00002634 # e.g. "\ No newline at end of file"
2635 $ctext insert end "$line\n" filesep
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002636 } else {
2637 # Something else we don't recognize
2638 if {$curdifftag != "Comments"} {
2639 $ctext insert end "\n"
2640 $ctext tag add $curdifftag $curtagstart end
2641 set curtagstart [$ctext index "end - 1c"]
2642 set curdifftag Comments
2643 }
2644 $ctext insert end "$line\n" filesep
2645 }
2646 }
2647 $ctext conf -state disabled
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002648 if {[clock clicks -milliseconds] >= $nextupdate} {
2649 incr nextupdate 100
2650 fileevent $bdf readable {}
2651 update
2652 fileevent $bdf readable "getblobdiffline $bdf {$ids}"
2653 }
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002654}
2655
Paul Mackerras39ad8572005-05-19 12:35:53 +00002656proc nextfile {} {
2657 global difffilestart ctext
2658 set here [$ctext index @0,0]
2659 for {set i 0} {[info exists difffilestart($i)]} {incr i} {
2660 if {[$ctext compare $difffilestart($i) > $here]} {
Paul Mackerras7eab2932005-07-20 12:25:54 -04002661 if {![info exists pos]
2662 || [$ctext compare $difffilestart($i) < $pos]} {
2663 set pos $difffilestart($i)
2664 }
Paul Mackerras39ad8572005-05-19 12:35:53 +00002665 }
2666 }
Paul Mackerras7eab2932005-07-20 12:25:54 -04002667 if {[info exists pos]} {
2668 $ctext yview $pos
2669 }
Paul Mackerras39ad8572005-05-19 12:35:53 +00002670}
2671
Paul Mackerrase5c2d852005-05-11 23:44:54 +00002672proc listboxsel {} {
Paul Mackerras7eab2932005-07-20 12:25:54 -04002673 global ctext cflist currentid
Paul Mackerras9a40c502005-05-12 23:46:16 +00002674 if {![info exists currentid]} return
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002675 set sel [lsort [$cflist curselection]]
2676 if {$sel eq {}} return
2677 set first [lindex $sel 0]
2678 catch {$ctext yview fmark.$first}
Paul Mackerras1db95b02005-05-09 04:08:39 +00002679}
2680
Paul Mackerras1d10f362005-05-15 12:55:47 +00002681proc setcoords {} {
2682 global linespc charspc canvx0 canvy0 mainfont
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10002683 global xspc1 xspc2 lthickness
Paul Mackerras8d858d12005-08-05 09:52:16 +10002684
Paul Mackerras1d10f362005-05-15 12:55:47 +00002685 set linespc [font metrics $mainfont -linespace]
2686 set charspc [font measure $mainfont "m"]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002687 set canvy0 [expr {int(3 + 0.5 * $linespc)}]
2688 set canvx0 [expr {int(3 + 0.5 * $linespc)}]
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10002689 set lthickness [expr {int($linespc / 9) + 1}]
Paul Mackerras8d858d12005-08-05 09:52:16 +10002690 set xspc1(0) $linespc
2691 set xspc2 $linespc
Paul Mackerras9a40c502005-05-12 23:46:16 +00002692}
Paul Mackerras1db95b02005-05-09 04:08:39 +00002693
Paul Mackerras1d10f362005-05-15 12:55:47 +00002694proc redisplay {} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002695 global canv canvy0 linespc numcommits
2696 global selectedline
2697
2698 set ymax [lindex [$canv cget -scrollregion] 3]
2699 if {$ymax eq {} || $ymax == 0} return
2700 set span [$canv yview]
2701 clear_display
2702 allcanvs conf -scrollregion \
2703 [list 0 0 0 [expr {$canvy0 + ($numcommits - 0.5) * $linespc + 2}]]
2704 allcanvs yview moveto [lindex $span 0]
2705 drawvisible
2706 if {[info exists selectedline]} {
2707 selectline $selectedline 0
Paul Mackerras1db95b02005-05-09 04:08:39 +00002708 }
2709}
Paul Mackerras1d10f362005-05-15 12:55:47 +00002710
2711proc incrfont {inc} {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002712 global mainfont namefont textfont ctext canv phase
Paul Mackerrascfb45632005-05-31 12:14:42 +00002713 global stopped entries
Paul Mackerras1d10f362005-05-15 12:55:47 +00002714 unmarkmatches
2715 set mainfont [lreplace $mainfont 1 1 [expr {[lindex $mainfont 1] + $inc}]]
2716 set namefont [lreplace $namefont 1 1 [expr {[lindex $namefont 1] + $inc}]]
2717 set textfont [lreplace $textfont 1 1 [expr {[lindex $textfont 1] + $inc}]]
2718 setcoords
2719 $ctext conf -font $textfont
2720 $ctext tag conf filesep -font [concat $textfont bold]
Paul Mackerras887fe3c2005-05-21 07:35:37 +00002721 foreach e $entries {
2722 $e conf -font $mainfont
2723 }
Paul Mackerras1d10f362005-05-15 12:55:47 +00002724 if {$phase == "getcommits"} {
2725 $canv itemconf textitems -font $mainfont
2726 }
2727 redisplay
Paul Mackerras1db95b02005-05-09 04:08:39 +00002728}
Paul Mackerras1d10f362005-05-15 12:55:47 +00002729
Paul Mackerrasee3dc722005-06-25 16:37:13 +10002730proc clearsha1 {} {
2731 global sha1entry sha1string
2732 if {[string length $sha1string] == 40} {
2733 $sha1entry delete 0 end
2734 }
2735}
2736
Paul Mackerras887fe3c2005-05-21 07:35:37 +00002737proc sha1change {n1 n2 op} {
2738 global sha1string currentid sha1but
2739 if {$sha1string == {}
2740 || ([info exists currentid] && $sha1string == $currentid)} {
2741 set state disabled
2742 } else {
2743 set state normal
2744 }
2745 if {[$sha1but cget -state] == $state} return
2746 if {$state == "normal"} {
2747 $sha1but conf -state normal -relief raised -text "Goto: "
2748 } else {
2749 $sha1but conf -state disabled -relief flat -text "SHA1 ID: "
2750 }
2751}
2752
2753proc gotocommit {} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002754 global sha1string currentid commitrow tagids
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002755 global displayorder numcommits
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04002756
Paul Mackerras887fe3c2005-05-21 07:35:37 +00002757 if {$sha1string == {}
2758 || ([info exists currentid] && $sha1string == $currentid)} return
2759 if {[info exists tagids($sha1string)]} {
2760 set id $tagids($sha1string)
2761 } else {
2762 set id [string tolower $sha1string]
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04002763 if {[regexp {^[0-9a-f]{4,39}$} $id]} {
2764 set matches {}
Paul Mackerras8ed16482006-03-02 22:56:44 +11002765 foreach i $displayorder {
2766 if {[string match $id* $i]} {
2767 lappend matches $i
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04002768 }
2769 }
2770 if {$matches ne {}} {
2771 if {[llength $matches] > 1} {
2772 error_popup "Short SHA1 id $id is ambiguous"
2773 return
2774 }
2775 set id [lindex $matches 0]
2776 }
2777 }
Paul Mackerras887fe3c2005-05-21 07:35:37 +00002778 }
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002779 if {[info exists commitrow($id)]} {
2780 selectline $commitrow($id) 1
Paul Mackerras887fe3c2005-05-21 07:35:37 +00002781 return
2782 }
Paul Mackerrasf3b8b3c2005-07-18 12:16:35 -04002783 if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} {
Paul Mackerras887fe3c2005-05-21 07:35:37 +00002784 set type "SHA1 id"
2785 } else {
2786 set type "Tag"
2787 }
2788 error_popup "$type $sha1string is not known"
2789}
2790
Paul Mackerras84ba7342005-06-17 00:12:26 +00002791proc lineenter {x y id} {
2792 global hoverx hovery hoverid hovertimer
2793 global commitinfo canv
2794
Paul Mackerras8ed16482006-03-02 22:56:44 +11002795 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerras84ba7342005-06-17 00:12:26 +00002796 set hoverx $x
2797 set hovery $y
2798 set hoverid $id
2799 if {[info exists hovertimer]} {
2800 after cancel $hovertimer
2801 }
2802 set hovertimer [after 500 linehover]
2803 $canv delete hover
2804}
2805
2806proc linemotion {x y id} {
2807 global hoverx hovery hoverid hovertimer
2808
2809 if {[info exists hoverid] && $id == $hoverid} {
2810 set hoverx $x
2811 set hovery $y
2812 if {[info exists hovertimer]} {
2813 after cancel $hovertimer
2814 }
2815 set hovertimer [after 500 linehover]
2816 }
2817}
2818
2819proc lineleave {id} {
2820 global hoverid hovertimer canv
2821
2822 if {[info exists hoverid] && $id == $hoverid} {
2823 $canv delete hover
2824 if {[info exists hovertimer]} {
2825 after cancel $hovertimer
2826 unset hovertimer
2827 }
2828 unset hoverid
2829 }
2830}
2831
2832proc linehover {} {
2833 global hoverx hovery hoverid hovertimer
2834 global canv linespc lthickness
2835 global commitinfo mainfont
2836
2837 set text [lindex $commitinfo($hoverid) 0]
2838 set ymax [lindex [$canv cget -scrollregion] 3]
2839 if {$ymax == {}} return
2840 set yfrac [lindex [$canv yview] 0]
2841 set x [expr {$hoverx + 2 * $linespc}]
2842 set y [expr {$hovery + $yfrac * $ymax - $linespc / 2}]
2843 set x0 [expr {$x - 2 * $lthickness}]
2844 set y0 [expr {$y - 2 * $lthickness}]
2845 set x1 [expr {$x + [font measure $mainfont $text] + 2 * $lthickness}]
2846 set y1 [expr {$y + $linespc + 2 * $lthickness}]
2847 set t [$canv create rectangle $x0 $y0 $x1 $y1 \
2848 -fill \#ffff80 -outline black -width 1 -tags hover]
2849 $canv raise $t
Frank Sorensone2464832005-10-30 02:06:46 -07002850 set t [$canv create text $x $y -anchor nw -text $text -tags hover -font $mainfont]
Paul Mackerras84ba7342005-06-17 00:12:26 +00002851 $canv raise $t
2852}
2853
Paul Mackerras9843c302005-08-30 10:57:11 +10002854proc clickisonarrow {id y} {
Paul Mackerrasf6342482006-02-28 10:02:03 +11002855 global lthickness idrowranges
Paul Mackerras9843c302005-08-30 10:57:11 +10002856
2857 set thresh [expr {2 * $lthickness + 6}]
Paul Mackerrasf6342482006-02-28 10:02:03 +11002858 set n [expr {[llength $idrowranges($id)] - 1}]
2859 for {set i 1} {$i < $n} {incr i} {
2860 set row [lindex $idrowranges($id) $i]
2861 if {abs([yc $row] - $y) < $thresh} {
2862 return $i
Paul Mackerras9843c302005-08-30 10:57:11 +10002863 }
2864 }
2865 return {}
2866}
2867
Paul Mackerrasf6342482006-02-28 10:02:03 +11002868proc arrowjump {id n y} {
2869 global idrowranges canv
Paul Mackerras9843c302005-08-30 10:57:11 +10002870
Paul Mackerrasf6342482006-02-28 10:02:03 +11002871 # 1 <-> 2, 3 <-> 4, etc...
2872 set n [expr {(($n - 1) ^ 1) + 1}]
2873 set row [lindex $idrowranges($id) $n]
2874 set yt [yc $row]
Paul Mackerras9843c302005-08-30 10:57:11 +10002875 set ymax [lindex [$canv cget -scrollregion] 3]
2876 if {$ymax eq {} || $ymax <= 0} return
2877 set view [$canv yview]
2878 set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
2879 set yfrac [expr {$yt / $ymax - $yspan / 2}]
2880 if {$yfrac < 0} {
2881 set yfrac 0
2882 }
Paul Mackerrasf6342482006-02-28 10:02:03 +11002883 allcanvs yview moveto $yfrac
Paul Mackerras9843c302005-08-30 10:57:11 +10002884}
2885
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002886proc lineclick {x y id isnew} {
Paul Mackerras9843c302005-08-30 10:57:11 +10002887 global ctext commitinfo children cflist canv thickerline
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002888
Paul Mackerras8ed16482006-03-02 22:56:44 +11002889 if {![info exists commitinfo($id)] && ![getcommit $id]} return
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002890 unmarkmatches
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002891 unselectline
Paul Mackerras9843c302005-08-30 10:57:11 +10002892 normalline
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002893 $canv delete hover
Paul Mackerras9843c302005-08-30 10:57:11 +10002894 # draw this line thicker than normal
Paul Mackerras9843c302005-08-30 10:57:11 +10002895 set thickerline $id
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002896 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10002897 if {$isnew} {
2898 set ymax [lindex [$canv cget -scrollregion] 3]
2899 if {$ymax eq {}} return
2900 set yfrac [lindex [$canv yview] 0]
2901 set y [expr {$y + $yfrac * $ymax}]
2902 }
2903 set dirn [clickisonarrow $id $y]
2904 if {$dirn ne {}} {
2905 arrowjump $id $dirn $y
2906 return
2907 }
2908
2909 if {$isnew} {
2910 addtohistory [list lineclick $x $y $id 0]
2911 }
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002912 # fill the details pane with info about this line
2913 $ctext conf -state normal
2914 $ctext delete 0.0 end
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002915 $ctext tag conf link -foreground blue -underline 1
2916 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
2917 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
2918 $ctext insert end "Parent:\t"
2919 $ctext insert end $id [list link link0]
2920 $ctext tag bind link0 <1> [list selbyid $id]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002921 set info $commitinfo($id)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002922 $ctext insert end "\n\t[lindex $info 0]\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002923 $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
Paul Mackerras232475d2005-11-15 10:34:03 +11002924 set date [formatdate [lindex $info 2]]
2925 $ctext insert end "\tDate:\t$date\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002926 if {[info exists children($id)]} {
2927 $ctext insert end "\nChildren:"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002928 set i 0
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002929 foreach child $children($id) {
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002930 incr i
Paul Mackerras8ed16482006-03-02 22:56:44 +11002931 if {![info exists commitinfo($child)] && ![getcommit $child]} continue
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002932 set info $commitinfo($child)
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002933 $ctext insert end "\n\t"
2934 $ctext insert end $child [list link link$i]
2935 $ctext tag bind link$i <1> [list selbyid $child]
2936 $ctext insert end "\n\t[lindex $info 0]"
2937 $ctext insert end "\n\tAuthor:\t[lindex $info 1]"
Paul Mackerras232475d2005-11-15 10:34:03 +11002938 set date [formatdate [lindex $info 2]]
2939 $ctext insert end "\n\tDate:\t$date\n"
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002940 }
2941 }
2942 $ctext conf -state disabled
2943
2944 $cflist delete 0 end
2945}
2946
Paul Mackerras9843c302005-08-30 10:57:11 +10002947proc normalline {} {
2948 global thickerline
2949 if {[info exists thickerline]} {
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002950 set id $thickerline
Paul Mackerras9843c302005-08-30 10:57:11 +10002951 unset thickerline
Paul Mackerrasc934a8a2006-03-02 23:00:44 +11002952 drawlines $id
Paul Mackerras9843c302005-08-30 10:57:11 +10002953 }
2954}
2955
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002956proc selbyid {id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002957 global commitrow
2958 if {[info exists commitrow($id)]} {
2959 selectline $commitrow($id) 1
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002960 }
2961}
2962
2963proc mstime {} {
2964 global startmstime
2965 if {![info exists startmstime]} {
2966 set startmstime [clock clicks -milliseconds]
2967 }
2968 return [format "%.3f" [expr {([clock click -milliseconds] - $startmstime) / 1000.0}]]
2969}
2970
2971proc rowmenu {x y id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002972 global rowctxmenu commitrow selectedline rowmenuid
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002973
Paul Mackerras9f1afe02006-02-19 22:44:47 +11002974 if {![info exists selectedline] || $commitrow($id) eq $selectedline} {
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002975 set state disabled
2976 } else {
2977 set state normal
2978 }
2979 $rowctxmenu entryconfigure 0 -state $state
2980 $rowctxmenu entryconfigure 1 -state $state
Paul Mackerras74daedb2005-06-27 19:27:32 +10002981 $rowctxmenu entryconfigure 2 -state $state
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002982 set rowmenuid $id
2983 tk_popup $rowctxmenu $x $y
2984}
2985
2986proc diffvssel {dirn} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002987 global rowmenuid selectedline displayorder
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002988
2989 if {![info exists selectedline]} return
2990 if {$dirn} {
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002991 set oldid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002992 set newid $rowmenuid
2993 } else {
2994 set oldid $rowmenuid
Paul Mackerras8f7d0ce2006-02-28 22:10:19 +11002995 set newid [lindex $displayorder $selectedline]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10002996 }
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10002997 addtohistory [list doseldiff $oldid $newid]
2998 doseldiff $oldid $newid
2999}
3000
3001proc doseldiff {oldid newid} {
3002 global ctext cflist
3003 global commitinfo
3004
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003005 $ctext conf -state normal
3006 $ctext delete 0.0 end
3007 $ctext mark set fmark.0 0.0
3008 $ctext mark gravity fmark.0 left
3009 $cflist delete 0 end
3010 $cflist insert end "Top"
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003011 $ctext insert end "From "
3012 $ctext tag conf link -foreground blue -underline 1
3013 $ctext tag bind link <Enter> { %W configure -cursor hand2 }
3014 $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
3015 $ctext tag bind link0 <1> [list selbyid $oldid]
3016 $ctext insert end $oldid [list link link0]
3017 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003018 $ctext insert end [lindex $commitinfo($oldid) 0]
Paul Mackerrasfa4da7b2005-08-08 09:47:22 +10003019 $ctext insert end "\n\nTo "
3020 $ctext tag bind link1 <1> [list selbyid $newid]
3021 $ctext insert end $newid [list link link1]
3022 $ctext insert end "\n "
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003023 $ctext insert end [lindex $commitinfo($newid) 0]
3024 $ctext insert end "\n"
3025 $ctext conf -state disabled
3026 $ctext tag delete Comments
3027 $ctext tag remove found 1.0 end
Paul Mackerrasd3272442005-11-28 20:41:56 +11003028 startdiff [list $oldid $newid]
Paul Mackerrasc8dfbcf2005-06-25 15:39:21 +10003029}
3030
Paul Mackerras74daedb2005-06-27 19:27:32 +10003031proc mkpatch {} {
3032 global rowmenuid currentid commitinfo patchtop patchnum
3033
3034 if {![info exists currentid]} return
3035 set oldid $currentid
3036 set oldhead [lindex $commitinfo($oldid) 0]
3037 set newid $rowmenuid
3038 set newhead [lindex $commitinfo($newid) 0]
3039 set top .patch
3040 set patchtop $top
3041 catch {destroy $top}
3042 toplevel $top
3043 label $top.title -text "Generate patch"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003044 grid $top.title - -pady 10
Paul Mackerras74daedb2005-06-27 19:27:32 +10003045 label $top.from -text "From:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003046 entry $top.fromsha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10003047 $top.fromsha1 insert 0 $oldid
3048 $top.fromsha1 conf -state readonly
3049 grid $top.from $top.fromsha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003050 entry $top.fromhead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10003051 $top.fromhead insert 0 $oldhead
3052 $top.fromhead conf -state readonly
3053 grid x $top.fromhead -sticky w
3054 label $top.to -text "To:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003055 entry $top.tosha1 -width 40 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10003056 $top.tosha1 insert 0 $newid
3057 $top.tosha1 conf -state readonly
3058 grid $top.to $top.tosha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003059 entry $top.tohead -width 60 -relief flat
Paul Mackerras74daedb2005-06-27 19:27:32 +10003060 $top.tohead insert 0 $newhead
3061 $top.tohead conf -state readonly
3062 grid x $top.tohead -sticky w
3063 button $top.rev -text "Reverse" -command mkpatchrev -padx 5
3064 grid $top.rev x -pady 10
3065 label $top.flab -text "Output file:"
3066 entry $top.fname -width 60
3067 $top.fname insert 0 [file normalize "patch$patchnum.patch"]
3068 incr patchnum
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003069 grid $top.flab $top.fname -sticky w
Paul Mackerras74daedb2005-06-27 19:27:32 +10003070 frame $top.buts
3071 button $top.buts.gen -text "Generate" -command mkpatchgo
3072 button $top.buts.can -text "Cancel" -command mkpatchcan
3073 grid $top.buts.gen $top.buts.can
3074 grid columnconfigure $top.buts 0 -weight 1 -uniform a
3075 grid columnconfigure $top.buts 1 -weight 1 -uniform a
3076 grid $top.buts - -pady 10 -sticky ew
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003077 focus $top.fname
Paul Mackerras74daedb2005-06-27 19:27:32 +10003078}
3079
3080proc mkpatchrev {} {
3081 global patchtop
3082
3083 set oldid [$patchtop.fromsha1 get]
3084 set oldhead [$patchtop.fromhead get]
3085 set newid [$patchtop.tosha1 get]
3086 set newhead [$patchtop.tohead get]
3087 foreach e [list fromsha1 fromhead tosha1 tohead] \
3088 v [list $newid $newhead $oldid $oldhead] {
3089 $patchtop.$e conf -state normal
3090 $patchtop.$e delete 0 end
3091 $patchtop.$e insert 0 $v
3092 $patchtop.$e conf -state readonly
3093 }
3094}
3095
3096proc mkpatchgo {} {
3097 global patchtop
3098
3099 set oldid [$patchtop.fromsha1 get]
3100 set newid [$patchtop.tosha1 get]
3101 set fname [$patchtop.fname get]
3102 if {[catch {exec git-diff-tree -p $oldid $newid >$fname &} err]} {
3103 error_popup "Error creating patch: $err"
3104 }
3105 catch {destroy $patchtop}
3106 unset patchtop
3107}
3108
3109proc mkpatchcan {} {
3110 global patchtop
3111
3112 catch {destroy $patchtop}
3113 unset patchtop
3114}
3115
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003116proc mktag {} {
3117 global rowmenuid mktagtop commitinfo
3118
3119 set top .maketag
3120 set mktagtop $top
3121 catch {destroy $top}
3122 toplevel $top
3123 label $top.title -text "Create tag"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003124 grid $top.title - -pady 10
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003125 label $top.id -text "ID:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003126 entry $top.sha1 -width 40 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003127 $top.sha1 insert 0 $rowmenuid
3128 $top.sha1 conf -state readonly
3129 grid $top.id $top.sha1 -sticky w
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003130 entry $top.head -width 60 -relief flat
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003131 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
3132 $top.head conf -state readonly
3133 grid x $top.head -sticky w
3134 label $top.tlab -text "Tag name:"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003135 entry $top.tag -width 60
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003136 grid $top.tlab $top.tag -sticky w
3137 frame $top.buts
3138 button $top.buts.gen -text "Create" -command mktaggo
3139 button $top.buts.can -text "Cancel" -command mktagcan
3140 grid $top.buts.gen $top.buts.can
3141 grid columnconfigure $top.buts 0 -weight 1 -uniform a
3142 grid columnconfigure $top.buts 1 -weight 1 -uniform a
3143 grid $top.buts - -pady 10 -sticky ew
3144 focus $top.tag
3145}
3146
3147proc domktag {} {
3148 global mktagtop env tagids idtags
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003149
3150 set id [$mktagtop.sha1 get]
3151 set tag [$mktagtop.tag get]
3152 if {$tag == {}} {
3153 error_popup "No tag name specified"
3154 return
3155 }
3156 if {[info exists tagids($tag)]} {
3157 error_popup "Tag \"$tag\" already exists"
3158 return
3159 }
3160 if {[catch {
Junio C Hamano73b6a6c2005-07-28 00:28:44 -07003161 set dir [gitdir]
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003162 set fname [file join $dir "refs/tags" $tag]
3163 set f [open $fname w]
3164 puts $f $id
3165 close $f
3166 } err]} {
3167 error_popup "Error creating tag: $err"
3168 return
3169 }
3170
3171 set tagids($tag) $id
3172 lappend idtags($id) $tag
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003173 redrawtags $id
3174}
3175
3176proc redrawtags {id} {
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003177 global canv linehtag commitrow idpos selectedline
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003178
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003179 if {![info exists commitrow($id)]} return
3180 drawcmitrow $commitrow($id)
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003181 $canv delete tag.$id
3182 set xt [eval drawtags $id $idpos($id)]
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003183 $canv coords $linehtag($commitrow($id)) $xt [lindex $idpos($id) 2]
3184 if {[info exists selectedline] && $selectedline == $commitrow($id)} {
Paul Mackerrasd6982062005-08-06 22:06:06 +10003185 selectline $selectedline 0
Paul Mackerrasbdbfbe32005-06-27 22:56:40 +10003186 }
3187}
3188
3189proc mktagcan {} {
3190 global mktagtop
3191
3192 catch {destroy $mktagtop}
3193 unset mktagtop
3194}
3195
3196proc mktaggo {} {
3197 domktag
3198 mktagcan
3199}
3200
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003201proc writecommit {} {
3202 global rowmenuid wrcomtop commitinfo wrcomcmd
3203
3204 set top .writecommit
3205 set wrcomtop $top
3206 catch {destroy $top}
3207 toplevel $top
3208 label $top.title -text "Write commit to file"
3209 grid $top.title - -pady 10
3210 label $top.id -text "ID:"
3211 entry $top.sha1 -width 40 -relief flat
3212 $top.sha1 insert 0 $rowmenuid
3213 $top.sha1 conf -state readonly
3214 grid $top.id $top.sha1 -sticky w
3215 entry $top.head -width 60 -relief flat
3216 $top.head insert 0 [lindex $commitinfo($rowmenuid) 0]
3217 $top.head conf -state readonly
3218 grid x $top.head -sticky w
3219 label $top.clab -text "Command:"
3220 entry $top.cmd -width 60 -textvariable wrcomcmd
3221 grid $top.clab $top.cmd -sticky w -pady 10
3222 label $top.flab -text "Output file:"
3223 entry $top.fname -width 60
3224 $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"]
3225 grid $top.flab $top.fname -sticky w
3226 frame $top.buts
3227 button $top.buts.gen -text "Write" -command wrcomgo
3228 button $top.buts.can -text "Cancel" -command wrcomcan
3229 grid $top.buts.gen $top.buts.can
3230 grid columnconfigure $top.buts 0 -weight 1 -uniform a
3231 grid columnconfigure $top.buts 1 -weight 1 -uniform a
3232 grid $top.buts - -pady 10 -sticky ew
3233 focus $top.fname
3234}
3235
3236proc wrcomgo {} {
3237 global wrcomtop
3238
3239 set id [$wrcomtop.sha1 get]
3240 set cmd "echo $id | [$wrcomtop.cmd get]"
3241 set fname [$wrcomtop.fname get]
3242 if {[catch {exec sh -c $cmd >$fname &} err]} {
3243 error_popup "Error writing commit: $err"
3244 }
3245 catch {destroy $wrcomtop}
3246 unset wrcomtop
3247}
3248
3249proc wrcomcan {} {
3250 global wrcomtop
3251
3252 catch {destroy $wrcomtop}
3253 unset wrcomtop
3254}
3255
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003256proc listrefs {id} {
3257 global idtags idheads idotherrefs
3258
3259 set x {}
3260 if {[info exists idtags($id)]} {
3261 set x $idtags($id)
3262 }
3263 set y {}
3264 if {[info exists idheads($id)]} {
3265 set y $idheads($id)
3266 }
3267 set z {}
3268 if {[info exists idotherrefs($id)]} {
3269 set z $idotherrefs($id)
3270 }
3271 return [list $x $y $z]
3272}
3273
3274proc rereadrefs {} {
3275 global idtags idheads idotherrefs
3276 global tagids headids otherrefids
3277
3278 set refids [concat [array names idtags] \
3279 [array names idheads] [array names idotherrefs]]
3280 foreach id $refids {
3281 if {![info exists ref($id)]} {
3282 set ref($id) [listrefs $id]
3283 }
3284 }
Paul Mackerrasf1d83ba2005-08-19 22:14:28 +10003285 readrefs
3286 set refids [lsort -unique [concat $refids [array names idtags] \
3287 [array names idheads] [array names idotherrefs]]]
3288 foreach id $refids {
3289 set v [listrefs $id]
3290 if {![info exists ref($id)] || $ref($id) != $v} {
3291 redrawtags $id
3292 }
3293 }
3294}
3295
Paul Mackerras106288c2005-08-19 23:11:39 +10003296proc showtag {tag isnew} {
3297 global ctext cflist tagcontents tagids linknum
3298
3299 if {$isnew} {
3300 addtohistory [list showtag $tag 0]
3301 }
3302 $ctext conf -state normal
3303 $ctext delete 0.0 end
3304 set linknum 0
3305 if {[info exists tagcontents($tag)]} {
3306 set text $tagcontents($tag)
3307 } else {
3308 set text "Tag: $tag\nId: $tagids($tag)"
3309 }
3310 appendwithlinks $text
3311 $ctext conf -state disabled
3312 $cflist delete 0 end
3313}
3314
Paul Mackerras1d10f362005-05-15 12:55:47 +00003315proc doquit {} {
3316 global stopped
3317 set stopped 100
3318 destroy .
3319}
3320
Paul Mackerras712fcc02005-11-30 09:28:16 +11003321proc doprefs {} {
3322 global maxwidth maxgraphpct diffopts findmergefiles
3323 global oldprefs prefstop
Paul Mackerras232475d2005-11-15 10:34:03 +11003324
Paul Mackerras712fcc02005-11-30 09:28:16 +11003325 set top .gitkprefs
3326 set prefstop $top
3327 if {[winfo exists $top]} {
3328 raise $top
3329 return
Paul Mackerras757f17b2005-11-21 09:56:07 +11003330 }
Paul Mackerras712fcc02005-11-30 09:28:16 +11003331 foreach v {maxwidth maxgraphpct diffopts findmergefiles} {
3332 set oldprefs($v) [set $v]
Paul Mackerras232475d2005-11-15 10:34:03 +11003333 }
Paul Mackerras712fcc02005-11-30 09:28:16 +11003334 toplevel $top
3335 wm title $top "Gitk preferences"
3336 label $top.ldisp -text "Commit list display options"
3337 grid $top.ldisp - -sticky w -pady 10
3338 label $top.spacer -text " "
3339 label $top.maxwidthl -text "Maximum graph width (lines)" \
3340 -font optionfont
3341 spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
3342 grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
3343 label $top.maxpctl -text "Maximum graph width (% of pane)" \
3344 -font optionfont
3345 spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
3346 grid x $top.maxpctl $top.maxpct -sticky w
3347 checkbutton $top.findm -variable findmergefiles
3348 label $top.findml -text "Include merges for \"Find\" in \"Files\"" \
3349 -font optionfont
3350 grid $top.findm $top.findml - -sticky w
3351 label $top.ddisp -text "Diff display options"
3352 grid $top.ddisp - -sticky w -pady 10
3353 label $top.diffoptl -text "Options for diff program" \
3354 -font optionfont
3355 entry $top.diffopt -width 20 -textvariable diffopts
3356 grid x $top.diffoptl $top.diffopt -sticky w
3357 frame $top.buts
3358 button $top.buts.ok -text "OK" -command prefsok
3359 button $top.buts.can -text "Cancel" -command prefscan
3360 grid $top.buts.ok $top.buts.can
3361 grid columnconfigure $top.buts 0 -weight 1 -uniform a
3362 grid columnconfigure $top.buts 1 -weight 1 -uniform a
3363 grid $top.buts - - -pady 10 -sticky ew
3364}
3365
3366proc prefscan {} {
3367 global maxwidth maxgraphpct diffopts findmergefiles
3368 global oldprefs prefstop
3369
3370 foreach v {maxwidth maxgraphpct diffopts findmergefiles} {
3371 set $v $oldprefs($v)
3372 }
3373 catch {destroy $prefstop}
3374 unset prefstop
3375}
3376
3377proc prefsok {} {
3378 global maxwidth maxgraphpct
3379 global oldprefs prefstop
3380
3381 catch {destroy $prefstop}
3382 unset prefstop
3383 if {$maxwidth != $oldprefs(maxwidth)
3384 || $maxgraphpct != $oldprefs(maxgraphpct)} {
3385 redisplay
3386 }
3387}
3388
3389proc formatdate {d} {
3390 return [clock format $d -format "%Y-%m-%d %H:%M:%S"]
Paul Mackerras232475d2005-11-15 10:34:03 +11003391}
3392
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11003393# This list of encoding names and aliases is distilled from
3394# http://www.iana.org/assignments/character-sets.
3395# Not all of them are supported by Tcl.
3396set encoding_aliases {
3397 { ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ASCII
3398 ISO646-US US-ASCII us IBM367 cp367 csASCII }
3399 { ISO-10646-UTF-1 csISO10646UTF1 }
3400 { ISO_646.basic:1983 ref csISO646basic1983 }
3401 { INVARIANT csINVARIANT }
3402 { ISO_646.irv:1983 iso-ir-2 irv csISO2IntlRefVersion }
3403 { BS_4730 iso-ir-4 ISO646-GB gb uk csISO4UnitedKingdom }
3404 { NATS-SEFI iso-ir-8-1 csNATSSEFI }
3405 { NATS-SEFI-ADD iso-ir-8-2 csNATSSEFIADD }
3406 { NATS-DANO iso-ir-9-1 csNATSDANO }
3407 { NATS-DANO-ADD iso-ir-9-2 csNATSDANOADD }
3408 { SEN_850200_B iso-ir-10 FI ISO646-FI ISO646-SE se csISO10Swedish }
3409 { SEN_850200_C iso-ir-11 ISO646-SE2 se2 csISO11SwedishForNames }
3410 { KS_C_5601-1987 iso-ir-149 KS_C_5601-1989 KSC_5601 korean csKSC56011987 }
3411 { ISO-2022-KR csISO2022KR }
3412 { EUC-KR csEUCKR }
3413 { ISO-2022-JP csISO2022JP }
3414 { ISO-2022-JP-2 csISO2022JP2 }
3415 { JIS_C6220-1969-jp JIS_C6220-1969 iso-ir-13 katakana x0201-7
3416 csISO13JISC6220jp }
3417 { JIS_C6220-1969-ro iso-ir-14 jp ISO646-JP csISO14JISC6220ro }
3418 { IT iso-ir-15 ISO646-IT csISO15Italian }
3419 { PT iso-ir-16 ISO646-PT csISO16Portuguese }
3420 { ES iso-ir-17 ISO646-ES csISO17Spanish }
3421 { greek7-old iso-ir-18 csISO18Greek7Old }
3422 { latin-greek iso-ir-19 csISO19LatinGreek }
3423 { DIN_66003 iso-ir-21 de ISO646-DE csISO21German }
3424 { NF_Z_62-010_(1973) iso-ir-25 ISO646-FR1 csISO25French }
3425 { Latin-greek-1 iso-ir-27 csISO27LatinGreek1 }
3426 { ISO_5427 iso-ir-37 csISO5427Cyrillic }
3427 { JIS_C6226-1978 iso-ir-42 csISO42JISC62261978 }
3428 { BS_viewdata iso-ir-47 csISO47BSViewdata }
3429 { INIS iso-ir-49 csISO49INIS }
3430 { INIS-8 iso-ir-50 csISO50INIS8 }
3431 { INIS-cyrillic iso-ir-51 csISO51INISCyrillic }
3432 { ISO_5427:1981 iso-ir-54 ISO5427Cyrillic1981 }
3433 { ISO_5428:1980 iso-ir-55 csISO5428Greek }
3434 { GB_1988-80 iso-ir-57 cn ISO646-CN csISO57GB1988 }
3435 { GB_2312-80 iso-ir-58 chinese csISO58GB231280 }
3436 { NS_4551-1 iso-ir-60 ISO646-NO no csISO60DanishNorwegian
3437 csISO60Norwegian1 }
3438 { NS_4551-2 ISO646-NO2 iso-ir-61 no2 csISO61Norwegian2 }
3439 { NF_Z_62-010 iso-ir-69 ISO646-FR fr csISO69French }
3440 { videotex-suppl iso-ir-70 csISO70VideotexSupp1 }
3441 { PT2 iso-ir-84 ISO646-PT2 csISO84Portuguese2 }
3442 { ES2 iso-ir-85 ISO646-ES2 csISO85Spanish2 }
3443 { MSZ_7795.3 iso-ir-86 ISO646-HU hu csISO86Hungarian }
3444 { JIS_C6226-1983 iso-ir-87 x0208 JIS_X0208-1983 csISO87JISX0208 }
3445 { greek7 iso-ir-88 csISO88Greek7 }
3446 { ASMO_449 ISO_9036 arabic7 iso-ir-89 csISO89ASMO449 }
3447 { iso-ir-90 csISO90 }
3448 { JIS_C6229-1984-a iso-ir-91 jp-ocr-a csISO91JISC62291984a }
3449 { JIS_C6229-1984-b iso-ir-92 ISO646-JP-OCR-B jp-ocr-b
3450 csISO92JISC62991984b }
3451 { JIS_C6229-1984-b-add iso-ir-93 jp-ocr-b-add csISO93JIS62291984badd }
3452 { JIS_C6229-1984-hand iso-ir-94 jp-ocr-hand csISO94JIS62291984hand }
3453 { JIS_C6229-1984-hand-add iso-ir-95 jp-ocr-hand-add
3454 csISO95JIS62291984handadd }
3455 { JIS_C6229-1984-kana iso-ir-96 csISO96JISC62291984kana }
3456 { ISO_2033-1983 iso-ir-98 e13b csISO2033 }
3457 { ANSI_X3.110-1983 iso-ir-99 CSA_T500-1983 NAPLPS csISO99NAPLPS }
3458 { ISO_8859-1:1987 iso-ir-100 ISO_8859-1 ISO-8859-1 latin1 l1 IBM819
3459 CP819 csISOLatin1 }
3460 { ISO_8859-2:1987 iso-ir-101 ISO_8859-2 ISO-8859-2 latin2 l2 csISOLatin2 }
3461 { T.61-7bit iso-ir-102 csISO102T617bit }
3462 { T.61-8bit T.61 iso-ir-103 csISO103T618bit }
3463 { ISO_8859-3:1988 iso-ir-109 ISO_8859-3 ISO-8859-3 latin3 l3 csISOLatin3 }
3464 { ISO_8859-4:1988 iso-ir-110 ISO_8859-4 ISO-8859-4 latin4 l4 csISOLatin4 }
3465 { ECMA-cyrillic iso-ir-111 KOI8-E csISO111ECMACyrillic }
3466 { CSA_Z243.4-1985-1 iso-ir-121 ISO646-CA csa7-1 ca csISO121Canadian1 }
3467 { CSA_Z243.4-1985-2 iso-ir-122 ISO646-CA2 csa7-2 csISO122Canadian2 }
3468 { CSA_Z243.4-1985-gr iso-ir-123 csISO123CSAZ24341985gr }
3469 { ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ISO-8859-6 ECMA-114 ASMO-708
3470 arabic csISOLatinArabic }
3471 { ISO_8859-6-E csISO88596E ISO-8859-6-E }
3472 { ISO_8859-6-I csISO88596I ISO-8859-6-I }
3473 { ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ISO-8859-7 ELOT_928 ECMA-118
3474 greek greek8 csISOLatinGreek }
3475 { T.101-G2 iso-ir-128 csISO128T101G2 }
3476 { ISO_8859-8:1988 iso-ir-138 ISO_8859-8 ISO-8859-8 hebrew
3477 csISOLatinHebrew }
3478 { ISO_8859-8-E csISO88598E ISO-8859-8-E }
3479 { ISO_8859-8-I csISO88598I ISO-8859-8-I }
3480 { CSN_369103 iso-ir-139 csISO139CSN369103 }
3481 { JUS_I.B1.002 iso-ir-141 ISO646-YU js yu csISO141JUSIB1002 }
3482 { ISO_6937-2-add iso-ir-142 csISOTextComm }
3483 { IEC_P27-1 iso-ir-143 csISO143IECP271 }
3484 { ISO_8859-5:1988 iso-ir-144 ISO_8859-5 ISO-8859-5 cyrillic
3485 csISOLatinCyrillic }
3486 { JUS_I.B1.003-serb iso-ir-146 serbian csISO146Serbian }
3487 { JUS_I.B1.003-mac macedonian iso-ir-147 csISO147Macedonian }
3488 { ISO_8859-9:1989 iso-ir-148 ISO_8859-9 ISO-8859-9 latin5 l5 csISOLatin5 }
3489 { greek-ccitt iso-ir-150 csISO150 csISO150GreekCCITT }
3490 { NC_NC00-10:81 cuba iso-ir-151 ISO646-CU csISO151Cuba }
3491 { ISO_6937-2-25 iso-ir-152 csISO6937Add }
3492 { GOST_19768-74 ST_SEV_358-88 iso-ir-153 csISO153GOST1976874 }
3493 { ISO_8859-supp iso-ir-154 latin1-2-5 csISO8859Supp }
3494 { ISO_10367-box iso-ir-155 csISO10367Box }
3495 { ISO-8859-10 iso-ir-157 l6 ISO_8859-10:1992 csISOLatin6 latin6 }
3496 { latin-lap lap iso-ir-158 csISO158Lap }
3497 { JIS_X0212-1990 x0212 iso-ir-159 csISO159JISX02121990 }
3498 { DS_2089 DS2089 ISO646-DK dk csISO646Danish }
3499 { us-dk csUSDK }
3500 { dk-us csDKUS }
3501 { JIS_X0201 X0201 csHalfWidthKatakana }
3502 { KSC5636 ISO646-KR csKSC5636 }
3503 { ISO-10646-UCS-2 csUnicode }
3504 { ISO-10646-UCS-4 csUCS4 }
3505 { DEC-MCS dec csDECMCS }
3506 { hp-roman8 roman8 r8 csHPRoman8 }
3507 { macintosh mac csMacintosh }
3508 { IBM037 cp037 ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl
3509 csIBM037 }
3510 { IBM038 EBCDIC-INT cp038 csIBM038 }
3511 { IBM273 CP273 csIBM273 }
3512 { IBM274 EBCDIC-BE CP274 csIBM274 }
3513 { IBM275 EBCDIC-BR cp275 csIBM275 }
3514 { IBM277 EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 }
3515 { IBM278 CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 }
3516 { IBM280 CP280 ebcdic-cp-it csIBM280 }
3517 { IBM281 EBCDIC-JP-E cp281 csIBM281 }
3518 { IBM284 CP284 ebcdic-cp-es csIBM284 }
3519 { IBM285 CP285 ebcdic-cp-gb csIBM285 }
3520 { IBM290 cp290 EBCDIC-JP-kana csIBM290 }
3521 { IBM297 cp297 ebcdic-cp-fr csIBM297 }
3522 { IBM420 cp420 ebcdic-cp-ar1 csIBM420 }
3523 { IBM423 cp423 ebcdic-cp-gr csIBM423 }
3524 { IBM424 cp424 ebcdic-cp-he csIBM424 }
3525 { IBM437 cp437 437 csPC8CodePage437 }
3526 { IBM500 CP500 ebcdic-cp-be ebcdic-cp-ch csIBM500 }
3527 { IBM775 cp775 csPC775Baltic }
3528 { IBM850 cp850 850 csPC850Multilingual }
3529 { IBM851 cp851 851 csIBM851 }
3530 { IBM852 cp852 852 csPCp852 }
3531 { IBM855 cp855 855 csIBM855 }
3532 { IBM857 cp857 857 csIBM857 }
3533 { IBM860 cp860 860 csIBM860 }
3534 { IBM861 cp861 861 cp-is csIBM861 }
3535 { IBM862 cp862 862 csPC862LatinHebrew }
3536 { IBM863 cp863 863 csIBM863 }
3537 { IBM864 cp864 csIBM864 }
3538 { IBM865 cp865 865 csIBM865 }
3539 { IBM866 cp866 866 csIBM866 }
3540 { IBM868 CP868 cp-ar csIBM868 }
3541 { IBM869 cp869 869 cp-gr csIBM869 }
3542 { IBM870 CP870 ebcdic-cp-roece ebcdic-cp-yu csIBM870 }
3543 { IBM871 CP871 ebcdic-cp-is csIBM871 }
3544 { IBM880 cp880 EBCDIC-Cyrillic csIBM880 }
3545 { IBM891 cp891 csIBM891 }
3546 { IBM903 cp903 csIBM903 }
3547 { IBM904 cp904 904 csIBBM904 }
3548 { IBM905 CP905 ebcdic-cp-tr csIBM905 }
3549 { IBM918 CP918 ebcdic-cp-ar2 csIBM918 }
3550 { IBM1026 CP1026 csIBM1026 }
3551 { EBCDIC-AT-DE csIBMEBCDICATDE }
3552 { EBCDIC-AT-DE-A csEBCDICATDEA }
3553 { EBCDIC-CA-FR csEBCDICCAFR }
3554 { EBCDIC-DK-NO csEBCDICDKNO }
3555 { EBCDIC-DK-NO-A csEBCDICDKNOA }
3556 { EBCDIC-FI-SE csEBCDICFISE }
3557 { EBCDIC-FI-SE-A csEBCDICFISEA }
3558 { EBCDIC-FR csEBCDICFR }
3559 { EBCDIC-IT csEBCDICIT }
3560 { EBCDIC-PT csEBCDICPT }
3561 { EBCDIC-ES csEBCDICES }
3562 { EBCDIC-ES-A csEBCDICESA }
3563 { EBCDIC-ES-S csEBCDICESS }
3564 { EBCDIC-UK csEBCDICUK }
3565 { EBCDIC-US csEBCDICUS }
3566 { UNKNOWN-8BIT csUnknown8BiT }
3567 { MNEMONIC csMnemonic }
3568 { MNEM csMnem }
3569 { VISCII csVISCII }
3570 { VIQR csVIQR }
3571 { KOI8-R csKOI8R }
3572 { IBM00858 CCSID00858 CP00858 PC-Multilingual-850+euro }
3573 { IBM00924 CCSID00924 CP00924 ebcdic-Latin9--euro }
3574 { IBM01140 CCSID01140 CP01140 ebcdic-us-37+euro }
3575 { IBM01141 CCSID01141 CP01141 ebcdic-de-273+euro }
3576 { IBM01142 CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro }
3577 { IBM01143 CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro }
3578 { IBM01144 CCSID01144 CP01144 ebcdic-it-280+euro }
3579 { IBM01145 CCSID01145 CP01145 ebcdic-es-284+euro }
3580 { IBM01146 CCSID01146 CP01146 ebcdic-gb-285+euro }
3581 { IBM01147 CCSID01147 CP01147 ebcdic-fr-297+euro }
3582 { IBM01148 CCSID01148 CP01148 ebcdic-international-500+euro }
3583 { IBM01149 CCSID01149 CP01149 ebcdic-is-871+euro }
3584 { IBM1047 IBM-1047 }
3585 { PTCP154 csPTCP154 PT154 CP154 Cyrillic-Asian }
3586 { Amiga-1251 Ami1251 Amiga1251 Ami-1251 }
3587 { UNICODE-1-1 csUnicode11 }
3588 { CESU-8 csCESU-8 }
3589 { BOCU-1 csBOCU-1 }
3590 { UNICODE-1-1-UTF-7 csUnicode11UTF7 }
3591 { ISO-8859-14 iso-ir-199 ISO_8859-14:1998 ISO_8859-14 latin8 iso-celtic
3592 l8 }
3593 { ISO-8859-15 ISO_8859-15 Latin-9 }
3594 { ISO-8859-16 iso-ir-226 ISO_8859-16:2001 ISO_8859-16 latin10 l10 }
3595 { GBK CP936 MS936 windows-936 }
3596 { JIS_Encoding csJISEncoding }
3597 { Shift_JIS MS_Kanji csShiftJIS }
3598 { Extended_UNIX_Code_Packed_Format_for_Japanese csEUCPkdFmtJapanese
3599 EUC-JP }
3600 { Extended_UNIX_Code_Fixed_Width_for_Japanese csEUCFixWidJapanese }
3601 { ISO-10646-UCS-Basic csUnicodeASCII }
3602 { ISO-10646-Unicode-Latin1 csUnicodeLatin1 ISO-10646 }
3603 { ISO-Unicode-IBM-1261 csUnicodeIBM1261 }
3604 { ISO-Unicode-IBM-1268 csUnicodeIBM1268 }
3605 { ISO-Unicode-IBM-1276 csUnicodeIBM1276 }
3606 { ISO-Unicode-IBM-1264 csUnicodeIBM1264 }
3607 { ISO-Unicode-IBM-1265 csUnicodeIBM1265 }
3608 { ISO-8859-1-Windows-3.0-Latin-1 csWindows30Latin1 }
3609 { ISO-8859-1-Windows-3.1-Latin-1 csWindows31Latin1 }
3610 { ISO-8859-2-Windows-Latin-2 csWindows31Latin2 }
3611 { ISO-8859-9-Windows-Latin-5 csWindows31Latin5 }
3612 { Adobe-Standard-Encoding csAdobeStandardEncoding }
3613 { Ventura-US csVenturaUS }
3614 { Ventura-International csVenturaInternational }
3615 { PC8-Danish-Norwegian csPC8DanishNorwegian }
3616 { PC8-Turkish csPC8Turkish }
3617 { IBM-Symbols csIBMSymbols }
3618 { IBM-Thai csIBMThai }
3619 { HP-Legal csHPLegal }
3620 { HP-Pi-font csHPPiFont }
3621 { HP-Math8 csHPMath8 }
3622 { Adobe-Symbol-Encoding csHPPSMath }
3623 { HP-DeskTop csHPDesktop }
3624 { Ventura-Math csVenturaMath }
3625 { Microsoft-Publishing csMicrosoftPublishing }
3626 { Windows-31J csWindows31J }
3627 { GB2312 csGB2312 }
3628 { Big5 csBig5 }
3629}
3630
3631proc tcl_encoding {enc} {
3632 global encoding_aliases
3633 set names [encoding names]
3634 set lcnames [string tolower $names]
3635 set enc [string tolower $enc]
3636 set i [lsearch -exact $lcnames $enc]
3637 if {$i < 0} {
3638 # look for "isonnn" instead of "iso-nnn" or "iso_nnn"
3639 if {[regsub {^iso[-_]} $enc iso encx]} {
3640 set i [lsearch -exact $lcnames $encx]
3641 }
3642 }
3643 if {$i < 0} {
3644 foreach l $encoding_aliases {
3645 set ll [string tolower $l]
3646 if {[lsearch -exact $ll $enc] < 0} continue
3647 # look through the aliases for one that tcl knows about
3648 foreach e $ll {
3649 set i [lsearch -exact $lcnames $e]
3650 if {$i < 0} {
3651 if {[regsub {^iso[-_]} $e iso ex]} {
3652 set i [lsearch -exact $lcnames $ex]
3653 }
3654 }
3655 if {$i >= 0} break
3656 }
3657 break
3658 }
3659 }
3660 if {$i >= 0} {
3661 return [lindex $names $i]
3662 }
3663 return {}
3664}
3665
Paul Mackerras1d10f362005-05-15 12:55:47 +00003666# defaults...
3667set datemode 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00003668set diffopts "-U 5 -p"
Paul Mackerras4a2139f2005-06-29 09:47:48 +10003669set wrcomcmd "git-diff-tree --stdin -p --pretty"
Junio C Hamano671bc152005-11-27 16:12:51 -08003670
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11003671set gitencoding {}
Junio C Hamano671bc152005-11-27 16:12:51 -08003672catch {
3673 set gitencoding [exec git-repo-config --get i18n.commitencoding]
3674}
3675if {$gitencoding == ""} {
Paul Mackerrasfd8ccbe2005-12-07 23:28:22 +11003676 set gitencoding "utf-8"
3677}
3678set tclencoding [tcl_encoding $gitencoding]
3679if {$tclencoding == {}} {
3680 puts stderr "Warning: encoding $gitencoding is not supported by Tcl/Tk"
Junio C Hamano671bc152005-11-27 16:12:51 -08003681}
Paul Mackerras1d10f362005-05-15 12:55:47 +00003682
3683set mainfont {Helvetica 9}
Paul Mackerras1d10f362005-05-15 12:55:47 +00003684set textfont {Courier 9}
Paul Mackerrasb74fd572005-07-16 07:46:13 -04003685set findmergefiles 0
Paul Mackerras8d858d12005-08-05 09:52:16 +10003686set maxgraphpct 50
Paul Mackerrasf6075eb2005-08-18 09:30:10 +10003687set maxwidth 16
Paul Mackerras232475d2005-11-15 10:34:03 +11003688set revlistorder 0
Paul Mackerras757f17b2005-11-21 09:56:07 +11003689set fastdate 0
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003690set uparrowlen 7
3691set downarrowlen 7
3692set mingaplen 30
Paul Mackerras1d10f362005-05-15 12:55:47 +00003693
3694set colors {green red blue magenta darkgrey brown orange}
Paul Mackerras1d10f362005-05-15 12:55:47 +00003695
3696catch {source ~/.gitk}
3697
Paul Mackerras17386062005-05-18 22:51:00 +00003698set namefont $mainfont
Paul Mackerras712fcc02005-11-30 09:28:16 +11003699
3700font create optionfont -family sans-serif -size -12
Paul Mackerras17386062005-05-18 22:51:00 +00003701
Paul Mackerras1d10f362005-05-15 12:55:47 +00003702set revtreeargs {}
3703foreach arg $argv {
3704 switch -regexp -- $arg {
3705 "^$" { }
Paul Mackerras1d10f362005-05-15 12:55:47 +00003706 "^-d" { set datemode 1 }
Paul Mackerras1d10f362005-05-15 12:55:47 +00003707 default {
3708 lappend revtreeargs $arg
3709 }
3710 }
3711}
3712
Paul Mackerrasaa81d972006-02-28 11:27:12 +11003713# check that we can find a .git directory somewhere...
3714set gitdir [gitdir]
3715if {![file isdirectory $gitdir]} {
3716 error_popup "Cannot find the git directory \"$gitdir\"."
3717 exit 1
3718}
3719
Paul Mackerrasd6982062005-08-06 22:06:06 +10003720set history {}
3721set historyindex 0
3722
Paul Mackerras9f1afe02006-02-19 22:44:47 +11003723set optim_delay 16
3724
Paul Mackerras1d10f362005-05-15 12:55:47 +00003725set stopped 0
Paul Mackerras0fba86b2005-05-16 23:54:58 +00003726set stuffsaved 0
Paul Mackerras74daedb2005-06-27 19:27:32 +10003727set patchnum 0
Paul Mackerras1d10f362005-05-15 12:55:47 +00003728setcoords
Sven Verdoolaegeb5c2f302005-11-29 22:15:51 +01003729makewindow $revtreeargs
Paul Mackerras887fe3c2005-05-21 07:35:37 +00003730readrefs
Paul Mackerras1d10f362005-05-15 12:55:47 +00003731getcommits $revtreeargs