]>
Commit | Line | Data |
---|---|---|
1db95b00 PM |
1 | #!/bin/sh |
2 | # Tcl ignores the next line -*- tcl -*- \ | |
9e026d39 | 3 | exec wish "$0" -- "$@" |
1db95b00 | 4 | |
e1a7c81f | 5 | # Copyright (C) 2005-2006 Paul Mackerras. All rights reserved. |
1db95b00 PM |
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 | ||
73b6a6cb JH |
10 | proc gitdir {} { |
11 | global env | |
12 | if {[info exists env(GIT_DIR)]} { | |
13 | return $env(GIT_DIR) | |
14 | } else { | |
5024baa4 | 15 | return [exec git rev-parse --git-dir] |
73b6a6cb JH |
16 | } |
17 | } | |
18 | ||
7eb3cb9c PM |
19 | # A simple scheduler for compute-intensive stuff. |
20 | # The aim is to make sure that event handlers for GUI actions can | |
21 | # run at least every 50-100 ms. Unfortunately fileevent handlers are | |
22 | # run before X event handlers, so reading from a fast source can | |
23 | # make the GUI completely unresponsive. | |
24 | proc run args { | |
25 | global isonrunq runq | |
26 | ||
27 | set script $args | |
28 | if {[info exists isonrunq($script)]} return | |
29 | if {$runq eq {}} { | |
30 | after idle dorunq | |
31 | } | |
32 | lappend runq [list {} $script] | |
33 | set isonrunq($script) 1 | |
34 | } | |
35 | ||
36 | proc filerun {fd script} { | |
37 | fileevent $fd readable [list filereadable $fd $script] | |
38 | } | |
39 | ||
40 | proc filereadable {fd script} { | |
41 | global runq | |
42 | ||
43 | fileevent $fd readable {} | |
44 | if {$runq eq {}} { | |
45 | after idle dorunq | |
46 | } | |
47 | lappend runq [list $fd $script] | |
48 | } | |
49 | ||
50 | proc dorunq {} { | |
51 | global isonrunq runq | |
52 | ||
53 | set tstart [clock clicks -milliseconds] | |
54 | set t0 $tstart | |
55 | while {$runq ne {}} { | |
56 | set fd [lindex $runq 0 0] | |
57 | set script [lindex $runq 0 1] | |
58 | set repeat [eval $script] | |
59 | set t1 [clock clicks -milliseconds] | |
60 | set t [expr {$t1 - $t0}] | |
61 | set runq [lrange $runq 1 end] | |
62 | if {$repeat ne {} && $repeat} { | |
63 | if {$fd eq {} || $repeat == 2} { | |
64 | # script returns 1 if it wants to be readded | |
65 | # file readers return 2 if they could do more straight away | |
66 | lappend runq [list $fd $script] | |
67 | } else { | |
68 | fileevent $fd readable [list filereadable $fd $script] | |
69 | } | |
70 | } elseif {$fd eq {}} { | |
71 | unset isonrunq($script) | |
72 | } | |
73 | set t0 $t1 | |
74 | if {$t1 - $tstart >= 80} break | |
75 | } | |
76 | if {$runq ne {}} { | |
77 | after idle dorunq | |
78 | } | |
79 | } | |
80 | ||
81 | # Start off a git rev-list process and arrange to read its output | |
da7c24dd | 82 | proc start_rev_list {view} { |
7eb3cb9c | 83 | global startmsecs |
9f1afe05 | 84 | global commfd leftover tclencoding datemode |
098dd8a3 | 85 | global viewargs viewfiles commitidx |
219ea3a9 | 86 | global lookingforhead showlocalchanges |
9ccbdfbf | 87 | |
9ccbdfbf | 88 | set startmsecs [clock clicks -milliseconds] |
da7c24dd | 89 | set commitidx($view) 0 |
9f1afe05 PM |
90 | set order "--topo-order" |
91 | if {$datemode} { | |
92 | set order "--date-order" | |
93 | } | |
418c4c7b | 94 | if {[catch { |
cdaee5db PM |
95 | set fd [open [concat | git log -z --pretty=raw $order --parents \ |
96 | --boundary $viewargs($view) "--" $viewfiles($view)] r] | |
418c4c7b | 97 | } err]} { |
cdaee5db | 98 | error_popup "Error executing git rev-list: $err" |
1d10f36d PM |
99 | exit 1 |
100 | } | |
da7c24dd PM |
101 | set commfd($view) $fd |
102 | set leftover($view) {} | |
219ea3a9 | 103 | set lookingforhead $showlocalchanges |
86da5b6c | 104 | fconfigure $fd -blocking 0 -translation lf -eofchar {} |
fd8ccbec | 105 | if {$tclencoding != {}} { |
da7c24dd | 106 | fconfigure $fd -encoding $tclencoding |
fd8ccbec | 107 | } |
7eb3cb9c | 108 | filerun $fd [list getcommitlines $fd $view] |
da7c24dd | 109 | nowbusy $view |
38ad0910 PM |
110 | } |
111 | ||
22626ef4 | 112 | proc stop_rev_list {} { |
da7c24dd | 113 | global commfd curview |
22626ef4 | 114 | |
da7c24dd PM |
115 | if {![info exists commfd($curview)]} return |
116 | set fd $commfd($curview) | |
22626ef4 | 117 | catch { |
da7c24dd | 118 | set pid [pid $fd] |
22626ef4 PM |
119 | exec kill $pid |
120 | } | |
da7c24dd PM |
121 | catch {close $fd} |
122 | unset commfd($curview) | |
22626ef4 PM |
123 | } |
124 | ||
a8aaf19c | 125 | proc getcommits {} { |
da7c24dd | 126 | global phase canv mainfont curview |
38ad0910 | 127 | |
38ad0910 | 128 | set phase getcommits |
da7c24dd PM |
129 | initlayout |
130 | start_rev_list $curview | |
098dd8a3 | 131 | show_status "Reading commits..." |
1d10f36d PM |
132 | } |
133 | ||
da7c24dd | 134 | proc getcommitlines {fd view} { |
7eb3cb9c | 135 | global commitlisted |
da7c24dd | 136 | global leftover commfd |
8ed16484 | 137 | global displayorder commitidx commitrow commitdata |
6a90bff1 PM |
138 | global parentlist children curview hlview |
139 | global vparentlist vdisporder vcmitlisted | |
9ccbdfbf | 140 | |
d1e46756 | 141 | set stuff [read $fd 500000] |
005a2f4e PM |
142 | # git log doesn't terminate the last commit with a null... |
143 | if {$stuff == {} && $leftover($view) ne {} && [eof $fd]} { | |
144 | set stuff "\0" | |
145 | } | |
b490a991 | 146 | if {$stuff == {}} { |
7eb3cb9c PM |
147 | if {![eof $fd]} { |
148 | return 1 | |
149 | } | |
098dd8a3 | 150 | global viewname |
da7c24dd | 151 | unset commfd($view) |
098dd8a3 | 152 | notbusy $view |
f0654861 | 153 | # set it blocking so we wait for the process to terminate |
da7c24dd | 154 | fconfigure $fd -blocking 1 |
098dd8a3 PM |
155 | if {[catch {close $fd} err]} { |
156 | set fv {} | |
157 | if {$view != $curview} { | |
158 | set fv " for the \"$viewname($view)\" view" | |
da7c24dd | 159 | } |
098dd8a3 PM |
160 | if {[string range $err 0 4] == "usage"} { |
161 | set err "Gitk: error reading commits$fv:\ | |
8974c6f9 | 162 | bad arguments to git rev-list." |
098dd8a3 PM |
163 | if {$viewname($view) eq "Command line"} { |
164 | append err \ | |
8974c6f9 | 165 | " (Note: arguments to gitk are passed to git rev-list\ |
098dd8a3 PM |
166 | to allow selection of commits to be displayed.)" |
167 | } | |
168 | } else { | |
169 | set err "Error reading commits$fv: $err" | |
170 | } | |
171 | error_popup $err | |
1d10f36d | 172 | } |
098dd8a3 | 173 | if {$view == $curview} { |
7eb3cb9c | 174 | run chewcommits $view |
9a40c50c | 175 | } |
7eb3cb9c | 176 | return 0 |
9a40c50c | 177 | } |
b490a991 | 178 | set start 0 |
8f7d0cec | 179 | set gotsome 0 |
b490a991 PM |
180 | while 1 { |
181 | set i [string first "\0" $stuff $start] | |
182 | if {$i < 0} { | |
da7c24dd | 183 | append leftover($view) [string range $stuff $start end] |
9f1afe05 | 184 | break |
9ccbdfbf | 185 | } |
b490a991 | 186 | if {$start == 0} { |
da7c24dd | 187 | set cmit $leftover($view) |
8f7d0cec | 188 | append cmit [string range $stuff 0 [expr {$i - 1}]] |
da7c24dd | 189 | set leftover($view) {} |
8f7d0cec PM |
190 | } else { |
191 | set cmit [string range $stuff $start [expr {$i - 1}]] | |
b490a991 PM |
192 | } |
193 | set start [expr {$i + 1}] | |
e5ea701b PM |
194 | set j [string first "\n" $cmit] |
195 | set ok 0 | |
16c1ff96 | 196 | set listed 1 |
c961b228 PM |
197 | if {$j >= 0 && [string match "commit *" $cmit]} { |
198 | set ids [string range $cmit 7 [expr {$j - 1}]] | |
199 | if {[string match {[-<>]*} $ids]} { | |
200 | switch -- [string index $ids 0] { | |
201 | "-" {set listed 0} | |
202 | "<" {set listed 2} | |
203 | ">" {set listed 3} | |
204 | } | |
16c1ff96 PM |
205 | set ids [string range $ids 1 end] |
206 | } | |
e5ea701b PM |
207 | set ok 1 |
208 | foreach id $ids { | |
8f7d0cec | 209 | if {[string length $id] != 40} { |
e5ea701b PM |
210 | set ok 0 |
211 | break | |
212 | } | |
213 | } | |
214 | } | |
215 | if {!$ok} { | |
7e952e79 PM |
216 | set shortcmit $cmit |
217 | if {[string length $shortcmit] > 80} { | |
218 | set shortcmit "[string range $shortcmit 0 80]..." | |
219 | } | |
c961b228 | 220 | error_popup "Can't parse git log output: {$shortcmit}" |
b490a991 PM |
221 | exit 1 |
222 | } | |
e5ea701b | 223 | set id [lindex $ids 0] |
16c1ff96 PM |
224 | if {$listed} { |
225 | set olds [lrange $ids 1 end] | |
50b44ece | 226 | set i 0 |
79b2c75e | 227 | foreach p $olds { |
50b44ece | 228 | if {$i == 0 || [lsearch -exact $olds $p] >= $i} { |
da7c24dd | 229 | lappend children($view,$p) $id |
50b44ece PM |
230 | } |
231 | incr i | |
79b2c75e | 232 | } |
16c1ff96 PM |
233 | } else { |
234 | set olds {} | |
235 | } | |
da7c24dd PM |
236 | if {![info exists children($view,$id)]} { |
237 | set children($view,$id) {} | |
79b2c75e | 238 | } |
f7a3e8d2 | 239 | set commitdata($id) [string range $cmit [expr {$j + 1}] end] |
da7c24dd PM |
240 | set commitrow($view,$id) $commitidx($view) |
241 | incr commitidx($view) | |
242 | if {$view == $curview} { | |
243 | lappend parentlist $olds | |
da7c24dd PM |
244 | lappend displayorder $id |
245 | lappend commitlisted $listed | |
246 | } else { | |
247 | lappend vparentlist($view) $olds | |
da7c24dd PM |
248 | lappend vdisporder($view) $id |
249 | lappend vcmitlisted($view) $listed | |
250 | } | |
8f7d0cec PM |
251 | set gotsome 1 |
252 | } | |
253 | if {$gotsome} { | |
7eb3cb9c | 254 | run chewcommits $view |
9ccbdfbf | 255 | } |
7eb3cb9c | 256 | return 2 |
9ccbdfbf PM |
257 | } |
258 | ||
7eb3cb9c PM |
259 | proc chewcommits {view} { |
260 | global curview hlview commfd | |
261 | global selectedline pending_select | |
262 | ||
263 | set more 0 | |
264 | if {$view == $curview} { | |
265 | set allread [expr {![info exists commfd($view)]}] | |
266 | set tlimit [expr {[clock clicks -milliseconds] + 50}] | |
267 | set more [layoutmore $tlimit $allread] | |
268 | if {$allread && !$more} { | |
8f489363 | 269 | global displayorder commitidx phase |
7eb3cb9c | 270 | global numcommits startmsecs |
9ccbdfbf | 271 | |
7eb3cb9c | 272 | if {[info exists pending_select]} { |
8f489363 | 273 | set row [first_real_row] |
7eb3cb9c PM |
274 | selectline $row 1 |
275 | } | |
276 | if {$commitidx($curview) > 0} { | |
277 | #set ms [expr {[clock clicks -milliseconds] - $startmsecs}] | |
278 | #puts "overall $ms ms for $numcommits commits" | |
279 | } else { | |
280 | show_status "No commits selected" | |
281 | } | |
282 | notbusy layout | |
283 | set phase {} | |
284 | } | |
b664550c | 285 | } |
7eb3cb9c PM |
286 | if {[info exists hlview] && $view == $hlview} { |
287 | vhighlightmore | |
b664550c | 288 | } |
7eb3cb9c | 289 | return $more |
1db95b00 PM |
290 | } |
291 | ||
292 | proc readcommit {id} { | |
8974c6f9 | 293 | if {[catch {set contents [exec git cat-file commit $id]}]} return |
8f7d0cec | 294 | parsecommit $id $contents 0 |
b490a991 PM |
295 | } |
296 | ||
50b44ece | 297 | proc updatecommits {} { |
098dd8a3 | 298 | global viewdata curview phase displayorder |
908c3585 | 299 | global children commitrow selectedline thickerline |
50b44ece | 300 | |
22626ef4 PM |
301 | if {$phase ne {}} { |
302 | stop_rev_list | |
303 | set phase {} | |
fd8ccbec | 304 | } |
d94f8cd6 | 305 | set n $curview |
da7c24dd PM |
306 | foreach id $displayorder { |
307 | catch {unset children($n,$id)} | |
308 | catch {unset commitrow($n,$id)} | |
309 | } | |
d94f8cd6 | 310 | set curview -1 |
908c3585 PM |
311 | catch {unset selectedline} |
312 | catch {unset thickerline} | |
d94f8cd6 | 313 | catch {unset viewdata($n)} |
fd8ccbec | 314 | readrefs |
e11f1233 PM |
315 | changedrefs |
316 | regetallcommits | |
d94f8cd6 | 317 | showview $n |
fd8ccbec PM |
318 | } |
319 | ||
8f7d0cec | 320 | proc parsecommit {id contents listed} { |
b5c2f306 SV |
321 | global commitinfo cdate |
322 | ||
323 | set inhdr 1 | |
324 | set comment {} | |
325 | set headline {} | |
326 | set auname {} | |
327 | set audate {} | |
328 | set comname {} | |
329 | set comdate {} | |
232475d3 PM |
330 | set hdrend [string first "\n\n" $contents] |
331 | if {$hdrend < 0} { | |
332 | # should never happen... | |
333 | set hdrend [string length $contents] | |
334 | } | |
335 | set header [string range $contents 0 [expr {$hdrend - 1}]] | |
336 | set comment [string range $contents [expr {$hdrend + 2}] end] | |
337 | foreach line [split $header "\n"] { | |
338 | set tag [lindex $line 0] | |
339 | if {$tag == "author"} { | |
340 | set audate [lindex $line end-1] | |
341 | set auname [lrange $line 1 end-2] | |
342 | } elseif {$tag == "committer"} { | |
343 | set comdate [lindex $line end-1] | |
344 | set comname [lrange $line 1 end-2] | |
1db95b00 PM |
345 | } |
346 | } | |
232475d3 | 347 | set headline {} |
43c25074 PM |
348 | # take the first non-blank line of the comment as the headline |
349 | set headline [string trimleft $comment] | |
350 | set i [string first "\n" $headline] | |
232475d3 | 351 | if {$i >= 0} { |
43c25074 PM |
352 | set headline [string range $headline 0 $i] |
353 | } | |
354 | set headline [string trimright $headline] | |
355 | set i [string first "\r" $headline] | |
356 | if {$i >= 0} { | |
357 | set headline [string trimright [string range $headline 0 $i]] | |
232475d3 PM |
358 | } |
359 | if {!$listed} { | |
8974c6f9 TH |
360 | # git rev-list indents the comment by 4 spaces; |
361 | # if we got this via git cat-file, add the indentation | |
232475d3 PM |
362 | set newcomment {} |
363 | foreach line [split $comment "\n"] { | |
364 | append newcomment " " | |
365 | append newcomment $line | |
f6e2869f | 366 | append newcomment "\n" |
232475d3 PM |
367 | } |
368 | set comment $newcomment | |
1db95b00 PM |
369 | } |
370 | if {$comdate != {}} { | |
cfb4563c | 371 | set cdate($id) $comdate |
1db95b00 | 372 | } |
e5c2d856 PM |
373 | set commitinfo($id) [list $headline $auname $audate \ |
374 | $comname $comdate $comment] | |
1db95b00 PM |
375 | } |
376 | ||
f7a3e8d2 | 377 | proc getcommit {id} { |
79b2c75e | 378 | global commitdata commitinfo |
8ed16484 | 379 | |
f7a3e8d2 PM |
380 | if {[info exists commitdata($id)]} { |
381 | parsecommit $id $commitdata($id) 1 | |
8ed16484 PM |
382 | } else { |
383 | readcommit $id | |
384 | if {![info exists commitinfo($id)]} { | |
385 | set commitinfo($id) {"No commit information available"} | |
8ed16484 PM |
386 | } |
387 | } | |
388 | return 1 | |
389 | } | |
390 | ||
887fe3c4 | 391 | proc readrefs {} { |
62d3ea65 | 392 | global tagids idtags headids idheads tagobjid |
219ea3a9 | 393 | global otherrefids idotherrefs mainhead mainheadid |
106288cb | 394 | |
b5c2f306 SV |
395 | foreach v {tagids idtags headids idheads otherrefids idotherrefs} { |
396 | catch {unset $v} | |
397 | } | |
62d3ea65 PM |
398 | set refd [open [list | git show-ref -d] r] |
399 | while {[gets $refd line] >= 0} { | |
400 | if {[string index $line 40] ne " "} continue | |
401 | set id [string range $line 0 39] | |
402 | set ref [string range $line 41 end] | |
403 | if {![string match "refs/*" $ref]} continue | |
404 | set name [string range $ref 5 end] | |
405 | if {[string match "remotes/*" $name]} { | |
406 | if {![string match "*/HEAD" $name]} { | |
407 | set headids($name) $id | |
408 | lappend idheads($id) $name | |
f1d83ba3 | 409 | } |
62d3ea65 PM |
410 | } elseif {[string match "heads/*" $name]} { |
411 | set name [string range $name 6 end] | |
36a7cad6 JH |
412 | set headids($name) $id |
413 | lappend idheads($id) $name | |
62d3ea65 PM |
414 | } elseif {[string match "tags/*" $name]} { |
415 | # this lets refs/tags/foo^{} overwrite refs/tags/foo, | |
416 | # which is what we want since the former is the commit ID | |
417 | set name [string range $name 5 end] | |
418 | if {[string match "*^{}" $name]} { | |
419 | set name [string range $name 0 end-3] | |
420 | } else { | |
421 | set tagobjid($name) $id | |
422 | } | |
423 | set tagids($name) $id | |
424 | lappend idtags($id) $name | |
36a7cad6 JH |
425 | } else { |
426 | set otherrefids($name) $id | |
427 | lappend idotherrefs($id) $name | |
f1d83ba3 PM |
428 | } |
429 | } | |
062d671f | 430 | catch {close $refd} |
8a48571c | 431 | set mainhead {} |
219ea3a9 | 432 | set mainheadid {} |
8a48571c PM |
433 | catch { |
434 | set thehead [exec git symbolic-ref HEAD] | |
435 | if {[string match "refs/heads/*" $thehead]} { | |
436 | set mainhead [string range $thehead 11 end] | |
219ea3a9 PM |
437 | if {[info exists headids($mainhead)]} { |
438 | set mainheadid $headids($mainhead) | |
439 | } | |
8a48571c PM |
440 | } |
441 | } | |
887fe3c4 PM |
442 | } |
443 | ||
8f489363 PM |
444 | # skip over fake commits |
445 | proc first_real_row {} { | |
446 | global nullid nullid2 displayorder numcommits | |
447 | ||
448 | for {set row 0} {$row < $numcommits} {incr row} { | |
449 | set id [lindex $displayorder $row] | |
450 | if {$id ne $nullid && $id ne $nullid2} { | |
451 | break | |
452 | } | |
453 | } | |
454 | return $row | |
455 | } | |
456 | ||
e11f1233 PM |
457 | # update things for a head moved to a child of its previous location |
458 | proc movehead {id name} { | |
459 | global headids idheads | |
460 | ||
461 | removehead $headids($name) $name | |
462 | set headids($name) $id | |
463 | lappend idheads($id) $name | |
464 | } | |
465 | ||
466 | # update things when a head has been removed | |
467 | proc removehead {id name} { | |
468 | global headids idheads | |
469 | ||
470 | if {$idheads($id) eq $name} { | |
471 | unset idheads($id) | |
472 | } else { | |
473 | set i [lsearch -exact $idheads($id) $name] | |
474 | if {$i >= 0} { | |
475 | set idheads($id) [lreplace $idheads($id) $i $i] | |
476 | } | |
477 | } | |
478 | unset headids($name) | |
479 | } | |
480 | ||
e54be9e3 | 481 | proc show_error {w top msg} { |
df3d83b1 PM |
482 | message $w.m -text $msg -justify center -aspect 400 |
483 | pack $w.m -side top -fill x -padx 20 -pady 20 | |
e54be9e3 | 484 | button $w.ok -text OK -command "destroy $top" |
df3d83b1 | 485 | pack $w.ok -side bottom -fill x |
e54be9e3 PM |
486 | bind $top <Visibility> "grab $top; focus $top" |
487 | bind $top <Key-Return> "destroy $top" | |
488 | tkwait window $top | |
df3d83b1 PM |
489 | } |
490 | ||
098dd8a3 PM |
491 | proc error_popup msg { |
492 | set w .error | |
493 | toplevel $w | |
494 | wm transient $w . | |
e54be9e3 | 495 | show_error $w $w $msg |
098dd8a3 PM |
496 | } |
497 | ||
10299152 PM |
498 | proc confirm_popup msg { |
499 | global confirm_ok | |
500 | set confirm_ok 0 | |
501 | set w .confirm | |
502 | toplevel $w | |
503 | wm transient $w . | |
504 | message $w.m -text $msg -justify center -aspect 400 | |
505 | pack $w.m -side top -fill x -padx 20 -pady 20 | |
506 | button $w.ok -text OK -command "set confirm_ok 1; destroy $w" | |
507 | pack $w.ok -side left -fill x | |
508 | button $w.cancel -text Cancel -command "destroy $w" | |
509 | pack $w.cancel -side right -fill x | |
510 | bind $w <Visibility> "grab $w; focus $w" | |
511 | tkwait window $w | |
512 | return $confirm_ok | |
513 | } | |
514 | ||
d94f8cd6 | 515 | proc makewindow {} { |
fdedbcfb | 516 | global canv canv2 canv3 linespc charspc ctext cflist |
7e12f1a6 | 517 | global textfont mainfont uifont tabstop |
b74fd579 | 518 | global findtype findtypemenu findloc findstring fstring geometry |
887fe3c4 | 519 | global entries sha1entry sha1string sha1but |
94a2eede | 520 | global maincursor textcursor curtextcursor |
219ea3a9 | 521 | global rowctxmenu fakerowmenu mergemax wrapcomment |
60f7a7dc | 522 | global highlight_files gdttype |
3ea06f9f | 523 | global searchstring sstring |
60378c0c | 524 | global bgcolor fgcolor bglist fglist diffcolors selectbgcolor |
10299152 | 525 | global headctxmenu |
9a40c50c PM |
526 | |
527 | menu .bar | |
528 | .bar add cascade -label "File" -menu .bar.file | |
4840be66 | 529 | .bar configure -font $uifont |
9a40c50c | 530 | menu .bar.file |
50b44ece | 531 | .bar.file add command -label "Update" -command updatecommits |
f1d83ba3 | 532 | .bar.file add command -label "Reread references" -command rereadrefs |
1d10f36d | 533 | .bar.file add command -label "Quit" -command doquit |
4840be66 | 534 | .bar.file configure -font $uifont |
712fcc08 PM |
535 | menu .bar.edit |
536 | .bar add cascade -label "Edit" -menu .bar.edit | |
537 | .bar.edit add command -label "Preferences" -command doprefs | |
4840be66 | 538 | .bar.edit configure -font $uifont |
da7c24dd | 539 | |
fdedbcfb | 540 | menu .bar.view -font $uifont |
50b44ece | 541 | .bar add cascade -label "View" -menu .bar.view |
da7c24dd PM |
542 | .bar.view add command -label "New view..." -command {newview 0} |
543 | .bar.view add command -label "Edit view..." -command editview \ | |
544 | -state disabled | |
50b44ece PM |
545 | .bar.view add command -label "Delete view" -command delview -state disabled |
546 | .bar.view add separator | |
a90a6d24 PM |
547 | .bar.view add radiobutton -label "All files" -command {showview 0} \ |
548 | -variable selectedview -value 0 | |
40b87ff8 | 549 | |
9a40c50c PM |
550 | menu .bar.help |
551 | .bar add cascade -label "Help" -menu .bar.help | |
552 | .bar.help add command -label "About gitk" -command about | |
4e95e1f7 | 553 | .bar.help add command -label "Key bindings" -command keys |
4840be66 | 554 | .bar.help configure -font $uifont |
9a40c50c PM |
555 | . configure -menu .bar |
556 | ||
e9937d2a | 557 | # the gui has upper and lower half, parts of a paned window. |
0327d27a | 558 | panedwindow .ctop -orient vertical |
e9937d2a JH |
559 | |
560 | # possibly use assumed geometry | |
9ca72f4f | 561 | if {![info exists geometry(pwsash0)]} { |
e9937d2a JH |
562 | set geometry(topheight) [expr {15 * $linespc}] |
563 | set geometry(topwidth) [expr {80 * $charspc}] | |
564 | set geometry(botheight) [expr {15 * $linespc}] | |
565 | set geometry(botwidth) [expr {50 * $charspc}] | |
9ca72f4f ML |
566 | set geometry(pwsash0) "[expr {40 * $charspc}] 2" |
567 | set geometry(pwsash1) "[expr {60 * $charspc}] 2" | |
e9937d2a JH |
568 | } |
569 | ||
570 | # the upper half will have a paned window, a scroll bar to the right, and some stuff below | |
571 | frame .tf -height $geometry(topheight) -width $geometry(topwidth) | |
572 | frame .tf.histframe | |
573 | panedwindow .tf.histframe.pwclist -orient horizontal -sashpad 0 -handlesize 4 | |
574 | ||
575 | # create three canvases | |
576 | set cscroll .tf.histframe.csb | |
577 | set canv .tf.histframe.pwclist.canv | |
9ca72f4f | 578 | canvas $canv \ |
60378c0c | 579 | -selectbackground $selectbgcolor \ |
f8a2c0d1 | 580 | -background $bgcolor -bd 0 \ |
9f1afe05 | 581 | -yscrollincr $linespc -yscrollcommand "scrollcanv $cscroll" |
e9937d2a JH |
582 | .tf.histframe.pwclist add $canv |
583 | set canv2 .tf.histframe.pwclist.canv2 | |
9ca72f4f | 584 | canvas $canv2 \ |
60378c0c | 585 | -selectbackground $selectbgcolor \ |
f8a2c0d1 | 586 | -background $bgcolor -bd 0 -yscrollincr $linespc |
e9937d2a JH |
587 | .tf.histframe.pwclist add $canv2 |
588 | set canv3 .tf.histframe.pwclist.canv3 | |
9ca72f4f | 589 | canvas $canv3 \ |
60378c0c | 590 | -selectbackground $selectbgcolor \ |
f8a2c0d1 | 591 | -background $bgcolor -bd 0 -yscrollincr $linespc |
e9937d2a | 592 | .tf.histframe.pwclist add $canv3 |
9ca72f4f ML |
593 | eval .tf.histframe.pwclist sash place 0 $geometry(pwsash0) |
594 | eval .tf.histframe.pwclist sash place 1 $geometry(pwsash1) | |
e9937d2a JH |
595 | |
596 | # a scroll bar to rule them | |
597 | scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0 | |
598 | pack $cscroll -side right -fill y | |
599 | bind .tf.histframe.pwclist <Configure> {resizeclistpanes %W %w} | |
f8a2c0d1 | 600 | lappend bglist $canv $canv2 $canv3 |
e9937d2a | 601 | pack .tf.histframe.pwclist -fill both -expand 1 -side left |
98f350e5 | 602 | |
e9937d2a JH |
603 | # we have two button bars at bottom of top frame. Bar 1 |
604 | frame .tf.bar | |
605 | frame .tf.lbar -height 15 | |
606 | ||
607 | set sha1entry .tf.bar.sha1 | |
887fe3c4 | 608 | set entries $sha1entry |
e9937d2a | 609 | set sha1but .tf.bar.sha1label |
887fe3c4 | 610 | button $sha1but -text "SHA1 ID: " -state disabled -relief flat \ |
4840be66 | 611 | -command gotocommit -width 8 -font $uifont |
887fe3c4 | 612 | $sha1but conf -disabledforeground [$sha1but cget -foreground] |
e9937d2a | 613 | pack .tf.bar.sha1label -side left |
887fe3c4 PM |
614 | entry $sha1entry -width 40 -font $textfont -textvariable sha1string |
615 | trace add variable sha1string write sha1change | |
98f350e5 | 616 | pack $sha1entry -side left -pady 2 |
d698206c PM |
617 | |
618 | image create bitmap bm-left -data { | |
619 | #define left_width 16 | |
620 | #define left_height 16 | |
621 | static unsigned char left_bits[] = { | |
622 | 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00, | |
623 | 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00, | |
624 | 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01}; | |
625 | } | |
626 | image create bitmap bm-right -data { | |
627 | #define right_width 16 | |
628 | #define right_height 16 | |
629 | static unsigned char right_bits[] = { | |
630 | 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c, | |
631 | 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c, | |
632 | 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01}; | |
633 | } | |
e9937d2a | 634 | button .tf.bar.leftbut -image bm-left -command goback \ |
d698206c | 635 | -state disabled -width 26 |
e9937d2a JH |
636 | pack .tf.bar.leftbut -side left -fill y |
637 | button .tf.bar.rightbut -image bm-right -command goforw \ | |
d698206c | 638 | -state disabled -width 26 |
e9937d2a | 639 | pack .tf.bar.rightbut -side left -fill y |
d698206c | 640 | |
e9937d2a JH |
641 | button .tf.bar.findbut -text "Find" -command dofind -font $uifont |
642 | pack .tf.bar.findbut -side left | |
98f350e5 | 643 | set findstring {} |
e9937d2a | 644 | set fstring .tf.bar.findstring |
887fe3c4 | 645 | lappend entries $fstring |
908c3585 | 646 | entry $fstring -width 30 -font $textfont -textvariable findstring |
60f7a7dc | 647 | trace add variable findstring write find_change |
e9937d2a | 648 | pack $fstring -side left -expand 1 -fill x -in .tf.bar |
98f350e5 | 649 | set findtype Exact |
e9937d2a JH |
650 | set findtypemenu [tk_optionMenu .tf.bar.findtype \ |
651 | findtype Exact IgnCase Regexp] | |
60f7a7dc | 652 | trace add variable findtype write find_change |
e9937d2a JH |
653 | .tf.bar.findtype configure -font $uifont |
654 | .tf.bar.findtype.menu configure -font $uifont | |
98f350e5 | 655 | set findloc "All fields" |
e9937d2a | 656 | tk_optionMenu .tf.bar.findloc findloc "All fields" Headline \ |
60f7a7dc PM |
657 | Comments Author Committer |
658 | trace add variable findloc write find_change | |
e9937d2a JH |
659 | .tf.bar.findloc configure -font $uifont |
660 | .tf.bar.findloc.menu configure -font $uifont | |
661 | pack .tf.bar.findloc -side right | |
662 | pack .tf.bar.findtype -side right | |
663 | ||
664 | # build up the bottom bar of upper window | |
665 | label .tf.lbar.flabel -text "Highlight: Commits " \ | |
666 | -font $uifont | |
667 | pack .tf.lbar.flabel -side left -fill y | |
60f7a7dc | 668 | set gdttype "touching paths:" |
e9937d2a JH |
669 | set gm [tk_optionMenu .tf.lbar.gdttype gdttype "touching paths:" \ |
670 | "adding/removing string:"] | |
60f7a7dc PM |
671 | trace add variable gdttype write hfiles_change |
672 | $gm conf -font $uifont | |
e9937d2a JH |
673 | .tf.lbar.gdttype conf -font $uifont |
674 | pack .tf.lbar.gdttype -side left -fill y | |
675 | entry .tf.lbar.fent -width 25 -font $textfont \ | |
908c3585 PM |
676 | -textvariable highlight_files |
677 | trace add variable highlight_files write hfiles_change | |
e9937d2a JH |
678 | lappend entries .tf.lbar.fent |
679 | pack .tf.lbar.fent -side left -fill x -expand 1 | |
680 | label .tf.lbar.vlabel -text " OR in view" -font $uifont | |
681 | pack .tf.lbar.vlabel -side left -fill y | |
908c3585 | 682 | global viewhlmenu selectedhlview |
e9937d2a | 683 | set viewhlmenu [tk_optionMenu .tf.lbar.vhl selectedhlview None] |
3cd204e5 | 684 | $viewhlmenu entryconf None -command delvhighlight |
63b79191 | 685 | $viewhlmenu conf -font $uifont |
e9937d2a JH |
686 | .tf.lbar.vhl conf -font $uifont |
687 | pack .tf.lbar.vhl -side left -fill y | |
688 | label .tf.lbar.rlabel -text " OR " -font $uifont | |
689 | pack .tf.lbar.rlabel -side left -fill y | |
164ff275 | 690 | global highlight_related |
e9937d2a JH |
691 | set m [tk_optionMenu .tf.lbar.relm highlight_related None \ |
692 | "Descendent" "Not descendent" "Ancestor" "Not ancestor"] | |
164ff275 | 693 | $m conf -font $uifont |
e9937d2a | 694 | .tf.lbar.relm conf -font $uifont |
164ff275 | 695 | trace add variable highlight_related write vrel_change |
e9937d2a JH |
696 | pack .tf.lbar.relm -side left -fill y |
697 | ||
698 | # Finish putting the upper half of the viewer together | |
699 | pack .tf.lbar -in .tf -side bottom -fill x | |
700 | pack .tf.bar -in .tf -side bottom -fill x | |
701 | pack .tf.histframe -fill both -side top -expand 1 | |
702 | .ctop add .tf | |
9ca72f4f ML |
703 | .ctop paneconfigure .tf -height $geometry(topheight) |
704 | .ctop paneconfigure .tf -width $geometry(topwidth) | |
e9937d2a JH |
705 | |
706 | # now build up the bottom | |
707 | panedwindow .pwbottom -orient horizontal | |
708 | ||
709 | # lower left, a text box over search bar, scroll bar to the right | |
710 | # if we know window height, then that will set the lower text height, otherwise | |
711 | # we set lower text height which will drive window height | |
712 | if {[info exists geometry(main)]} { | |
713 | frame .bleft -width $geometry(botwidth) | |
714 | } else { | |
715 | frame .bleft -width $geometry(botwidth) -height $geometry(botheight) | |
716 | } | |
717 | frame .bleft.top | |
a8d610a2 | 718 | frame .bleft.mid |
e9937d2a JH |
719 | |
720 | button .bleft.top.search -text "Search" -command dosearch \ | |
3ea06f9f | 721 | -font $uifont |
e9937d2a JH |
722 | pack .bleft.top.search -side left -padx 5 |
723 | set sstring .bleft.top.sstring | |
3ea06f9f PM |
724 | entry $sstring -width 20 -font $textfont -textvariable searchstring |
725 | lappend entries $sstring | |
726 | trace add variable searchstring write incrsearch | |
727 | pack $sstring -side left -expand 1 -fill x | |
a8d610a2 PM |
728 | radiobutton .bleft.mid.diff -text "Diff" \ |
729 | -command changediffdisp -variable diffelide -value {0 0} | |
730 | radiobutton .bleft.mid.old -text "Old version" \ | |
731 | -command changediffdisp -variable diffelide -value {0 1} | |
732 | radiobutton .bleft.mid.new -text "New version" \ | |
733 | -command changediffdisp -variable diffelide -value {1 0} | |
734 | pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left | |
e9937d2a | 735 | set ctext .bleft.ctext |
f8a2c0d1 | 736 | text $ctext -background $bgcolor -foreground $fgcolor \ |
7e12f1a6 | 737 | -tabs "[expr {$tabstop * $charspc}]" \ |
f8a2c0d1 | 738 | -state disabled -font $textfont \ |
3ea06f9f | 739 | -yscrollcommand scrolltext -wrap none |
e9937d2a JH |
740 | scrollbar .bleft.sb -command "$ctext yview" |
741 | pack .bleft.top -side top -fill x | |
a8d610a2 | 742 | pack .bleft.mid -side top -fill x |
e9937d2a | 743 | pack .bleft.sb -side right -fill y |
d2610d11 | 744 | pack $ctext -side left -fill both -expand 1 |
f8a2c0d1 PM |
745 | lappend bglist $ctext |
746 | lappend fglist $ctext | |
d2610d11 | 747 | |
f1b86294 | 748 | $ctext tag conf comment -wrap $wrapcomment |
f0654861 | 749 | $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa" |
f8a2c0d1 PM |
750 | $ctext tag conf hunksep -fore [lindex $diffcolors 2] |
751 | $ctext tag conf d0 -fore [lindex $diffcolors 0] | |
752 | $ctext tag conf d1 -fore [lindex $diffcolors 1] | |
712fcc08 PM |
753 | $ctext tag conf m0 -fore red |
754 | $ctext tag conf m1 -fore blue | |
755 | $ctext tag conf m2 -fore green | |
756 | $ctext tag conf m3 -fore purple | |
757 | $ctext tag conf m4 -fore brown | |
b77b0278 PM |
758 | $ctext tag conf m5 -fore "#009090" |
759 | $ctext tag conf m6 -fore magenta | |
760 | $ctext tag conf m7 -fore "#808000" | |
761 | $ctext tag conf m8 -fore "#009000" | |
762 | $ctext tag conf m9 -fore "#ff0080" | |
763 | $ctext tag conf m10 -fore cyan | |
764 | $ctext tag conf m11 -fore "#b07070" | |
765 | $ctext tag conf m12 -fore "#70b0f0" | |
766 | $ctext tag conf m13 -fore "#70f0b0" | |
767 | $ctext tag conf m14 -fore "#f0b070" | |
768 | $ctext tag conf m15 -fore "#ff70b0" | |
712fcc08 | 769 | $ctext tag conf mmax -fore darkgrey |
b77b0278 | 770 | set mergemax 16 |
712fcc08 PM |
771 | $ctext tag conf mresult -font [concat $textfont bold] |
772 | $ctext tag conf msep -font [concat $textfont bold] | |
773 | $ctext tag conf found -back yellow | |
e5c2d856 | 774 | |
e9937d2a | 775 | .pwbottom add .bleft |
9ca72f4f | 776 | .pwbottom paneconfigure .bleft -width $geometry(botwidth) |
e9937d2a JH |
777 | |
778 | # lower right | |
779 | frame .bright | |
780 | frame .bright.mode | |
781 | radiobutton .bright.mode.patch -text "Patch" \ | |
f8b28a40 | 782 | -command reselectline -variable cmitmode -value "patch" |
d59c4b6f | 783 | .bright.mode.patch configure -font $uifont |
e9937d2a | 784 | radiobutton .bright.mode.tree -text "Tree" \ |
f8b28a40 | 785 | -command reselectline -variable cmitmode -value "tree" |
d59c4b6f | 786 | .bright.mode.tree configure -font $uifont |
e9937d2a JH |
787 | grid .bright.mode.patch .bright.mode.tree -sticky ew |
788 | pack .bright.mode -side top -fill x | |
789 | set cflist .bright.cfiles | |
7fcceed7 | 790 | set indent [font measure $mainfont "nn"] |
e9937d2a | 791 | text $cflist \ |
60378c0c | 792 | -selectbackground $selectbgcolor \ |
f8a2c0d1 PM |
793 | -background $bgcolor -foreground $fgcolor \ |
794 | -font $mainfont \ | |
7fcceed7 | 795 | -tabs [list $indent [expr {2 * $indent}]] \ |
e9937d2a | 796 | -yscrollcommand ".bright.sb set" \ |
7fcceed7 PM |
797 | -cursor [. cget -cursor] \ |
798 | -spacing1 1 -spacing3 1 | |
f8a2c0d1 PM |
799 | lappend bglist $cflist |
800 | lappend fglist $cflist | |
e9937d2a JH |
801 | scrollbar .bright.sb -command "$cflist yview" |
802 | pack .bright.sb -side right -fill y | |
d2610d11 | 803 | pack $cflist -side left -fill both -expand 1 |
89b11d3b PM |
804 | $cflist tag configure highlight \ |
805 | -background [$cflist cget -selectbackground] | |
63b79191 | 806 | $cflist tag configure bold -font [concat $mainfont bold] |
d2610d11 | 807 | |
e9937d2a JH |
808 | .pwbottom add .bright |
809 | .ctop add .pwbottom | |
1db95b00 | 810 | |
e9937d2a JH |
811 | # restore window position if known |
812 | if {[info exists geometry(main)]} { | |
813 | wm geometry . "$geometry(main)" | |
814 | } | |
815 | ||
d23d98d3 SP |
816 | if {[tk windowingsystem] eq {aqua}} { |
817 | set M1B M1 | |
818 | } else { | |
819 | set M1B Control | |
820 | } | |
821 | ||
e9937d2a JH |
822 | bind .pwbottom <Configure> {resizecdetpanes %W %w} |
823 | pack .ctop -fill both -expand 1 | |
c8dfbcf9 PM |
824 | bindall <1> {selcanvline %W %x %y} |
825 | #bindall <B1-Motion> {selcanvline %W %x %y} | |
314c3093 ML |
826 | if {[tk windowingsystem] == "win32"} { |
827 | bind . <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D } | |
828 | bind $ctext <MouseWheel> { windows_mousewheel_redirector %W %X %Y %D ; break } | |
829 | } else { | |
830 | bindall <ButtonRelease-4> "allcanvs yview scroll -5 units" | |
831 | bindall <ButtonRelease-5> "allcanvs yview scroll 5 units" | |
832 | } | |
be0cd098 PM |
833 | bindall <2> "canvscan mark %W %x %y" |
834 | bindall <B2-Motion> "canvscan dragto %W %x %y" | |
6e5f7203 RN |
835 | bindkey <Home> selfirstline |
836 | bindkey <End> sellastline | |
17386066 PM |
837 | bind . <Key-Up> "selnextline -1" |
838 | bind . <Key-Down> "selnextline 1" | |
4e7d6779 PM |
839 | bind . <Shift-Key-Up> "next_highlight -1" |
840 | bind . <Shift-Key-Down> "next_highlight 1" | |
6e5f7203 RN |
841 | bindkey <Key-Right> "goforw" |
842 | bindkey <Key-Left> "goback" | |
843 | bind . <Key-Prior> "selnextpage -1" | |
844 | bind . <Key-Next> "selnextpage 1" | |
d23d98d3 SP |
845 | bind . <$M1B-Home> "allcanvs yview moveto 0.0" |
846 | bind . <$M1B-End> "allcanvs yview moveto 1.0" | |
847 | bind . <$M1B-Key-Up> "allcanvs yview scroll -1 units" | |
848 | bind . <$M1B-Key-Down> "allcanvs yview scroll 1 units" | |
849 | bind . <$M1B-Key-Prior> "allcanvs yview scroll -1 pages" | |
850 | bind . <$M1B-Key-Next> "allcanvs yview scroll 1 pages" | |
cfb4563c PM |
851 | bindkey <Key-Delete> "$ctext yview scroll -1 pages" |
852 | bindkey <Key-BackSpace> "$ctext yview scroll -1 pages" | |
853 | bindkey <Key-space> "$ctext yview scroll 1 pages" | |
df3d83b1 PM |
854 | bindkey p "selnextline -1" |
855 | bindkey n "selnextline 1" | |
6e2dda35 RS |
856 | bindkey z "goback" |
857 | bindkey x "goforw" | |
858 | bindkey i "selnextline -1" | |
859 | bindkey k "selnextline 1" | |
860 | bindkey j "goback" | |
861 | bindkey l "goforw" | |
cfb4563c PM |
862 | bindkey b "$ctext yview scroll -1 pages" |
863 | bindkey d "$ctext yview scroll 18 units" | |
864 | bindkey u "$ctext yview scroll -18 units" | |
b74fd579 PM |
865 | bindkey / {findnext 1} |
866 | bindkey <Key-Return> {findnext 0} | |
df3d83b1 | 867 | bindkey ? findprev |
39ad8570 | 868 | bindkey f nextfile |
e7a09191 | 869 | bindkey <F5> updatecommits |
d23d98d3 SP |
870 | bind . <$M1B-q> doquit |
871 | bind . <$M1B-f> dofind | |
872 | bind . <$M1B-g> {findnext 0} | |
873 | bind . <$M1B-r> dosearchback | |
874 | bind . <$M1B-s> dosearch | |
875 | bind . <$M1B-equal> {incrfont 1} | |
876 | bind . <$M1B-KP_Add> {incrfont 1} | |
877 | bind . <$M1B-minus> {incrfont -1} | |
878 | bind . <$M1B-KP_Subtract> {incrfont -1} | |
b6047c5a | 879 | wm protocol . WM_DELETE_WINDOW doquit |
df3d83b1 | 880 | bind . <Button-1> "click %W" |
17386066 | 881 | bind $fstring <Key-Return> dofind |
887fe3c4 | 882 | bind $sha1entry <Key-Return> gotocommit |
ee3dc72e | 883 | bind $sha1entry <<PasteSelection>> clearsha1 |
7fcceed7 PM |
884 | bind $cflist <1> {sel_flist %W %x %y; break} |
885 | bind $cflist <B1-Motion> {sel_flist %W %x %y; break} | |
f8b28a40 | 886 | bind $cflist <ButtonRelease-1> {treeclick %W %x %y} |
3244729a | 887 | bind $cflist <Button-3> {pop_flist_menu %W %X %Y %x %y} |
ea13cba1 PM |
888 | |
889 | set maincursor [. cget -cursor] | |
890 | set textcursor [$ctext cget -cursor] | |
94a2eede | 891 | set curtextcursor $textcursor |
84ba7345 | 892 | |
c8dfbcf9 PM |
893 | set rowctxmenu .rowctxmenu |
894 | menu $rowctxmenu -tearoff 0 | |
895 | $rowctxmenu add command -label "Diff this -> selected" \ | |
896 | -command {diffvssel 0} | |
897 | $rowctxmenu add command -label "Diff selected -> this" \ | |
898 | -command {diffvssel 1} | |
74daedb6 | 899 | $rowctxmenu add command -label "Make patch" -command mkpatch |
bdbfbe3d | 900 | $rowctxmenu add command -label "Create tag" -command mktag |
4a2139f5 | 901 | $rowctxmenu add command -label "Write commit to file" -command writecommit |
d6ac1a86 | 902 | $rowctxmenu add command -label "Create new branch" -command mkbranch |
ca6d8f58 PM |
903 | $rowctxmenu add command -label "Cherry-pick this commit" \ |
904 | -command cherrypick | |
6fb735ae PM |
905 | $rowctxmenu add command -label "Reset HEAD branch to here" \ |
906 | -command resethead | |
10299152 | 907 | |
219ea3a9 PM |
908 | set fakerowmenu .fakerowmenu |
909 | menu $fakerowmenu -tearoff 0 | |
910 | $fakerowmenu add command -label "Diff this -> selected" \ | |
911 | -command {diffvssel 0} | |
912 | $fakerowmenu add command -label "Diff selected -> this" \ | |
913 | -command {diffvssel 1} | |
914 | $fakerowmenu add command -label "Make patch" -command mkpatch | |
915 | # $fakerowmenu add command -label "Commit" -command {mkcommit 0} | |
916 | # $fakerowmenu add command -label "Commit all" -command {mkcommit 1} | |
917 | # $fakerowmenu add command -label "Revert local changes" -command revertlocal | |
918 | ||
10299152 PM |
919 | set headctxmenu .headctxmenu |
920 | menu $headctxmenu -tearoff 0 | |
921 | $headctxmenu add command -label "Check out this branch" \ | |
922 | -command cobranch | |
923 | $headctxmenu add command -label "Remove this branch" \ | |
924 | -command rmbranch | |
3244729a PM |
925 | |
926 | global flist_menu | |
927 | set flist_menu .flistctxmenu | |
928 | menu $flist_menu -tearoff 0 | |
929 | $flist_menu add command -label "Highlight this too" \ | |
930 | -command {flist_hl 0} | |
931 | $flist_menu add command -label "Highlight this only" \ | |
932 | -command {flist_hl 1} | |
df3d83b1 PM |
933 | } |
934 | ||
314c3093 ML |
935 | # Windows sends all mouse wheel events to the current focused window, not |
936 | # the one where the mouse hovers, so bind those events here and redirect | |
937 | # to the correct window | |
938 | proc windows_mousewheel_redirector {W X Y D} { | |
939 | global canv canv2 canv3 | |
940 | set w [winfo containing -displayof $W $X $Y] | |
941 | if {$w ne ""} { | |
942 | set u [expr {$D < 0 ? 5 : -5}] | |
943 | if {$w == $canv || $w == $canv2 || $w == $canv3} { | |
944 | allcanvs yview scroll $u units | |
945 | } else { | |
946 | catch { | |
947 | $w yview scroll $u units | |
948 | } | |
949 | } | |
950 | } | |
951 | } | |
952 | ||
be0cd098 PM |
953 | # mouse-2 makes all windows scan vertically, but only the one |
954 | # the cursor is in scans horizontally | |
955 | proc canvscan {op w x y} { | |
956 | global canv canv2 canv3 | |
957 | foreach c [list $canv $canv2 $canv3] { | |
958 | if {$c == $w} { | |
959 | $c scan $op $x $y | |
960 | } else { | |
961 | $c scan $op 0 $y | |
962 | } | |
963 | } | |
964 | } | |
965 | ||
9f1afe05 PM |
966 | proc scrollcanv {cscroll f0 f1} { |
967 | $cscroll set $f0 $f1 | |
968 | drawfrac $f0 $f1 | |
908c3585 | 969 | flushhighlights |
9f1afe05 PM |
970 | } |
971 | ||
df3d83b1 PM |
972 | # when we make a key binding for the toplevel, make sure |
973 | # it doesn't get triggered when that key is pressed in the | |
974 | # find string entry widget. | |
975 | proc bindkey {ev script} { | |
887fe3c4 | 976 | global entries |
df3d83b1 PM |
977 | bind . $ev $script |
978 | set escript [bind Entry $ev] | |
979 | if {$escript == {}} { | |
980 | set escript [bind Entry <Key>] | |
981 | } | |
887fe3c4 PM |
982 | foreach e $entries { |
983 | bind $e $ev "$escript; break" | |
984 | } | |
df3d83b1 PM |
985 | } |
986 | ||
987 | # set the focus back to the toplevel for any click outside | |
887fe3c4 | 988 | # the entry widgets |
df3d83b1 | 989 | proc click {w} { |
bd441de4 ML |
990 | global ctext entries |
991 | foreach e [concat $entries $ctext] { | |
887fe3c4 | 992 | if {$w == $e} return |
df3d83b1 | 993 | } |
887fe3c4 | 994 | focus . |
0fba86b3 PM |
995 | } |
996 | ||
997 | proc savestuff {w} { | |
7e12f1a6 | 998 | global canv canv2 canv3 ctext cflist mainfont textfont uifont tabstop |
712fcc08 | 999 | global stuffsaved findmergefiles maxgraphpct |
219ea3a9 | 1000 | global maxwidth showneartags showlocalchanges |
098dd8a3 | 1001 | global viewname viewfiles viewargs viewperm nextviewnum |
f1b86294 | 1002 | global cmitmode wrapcomment |
60378c0c | 1003 | global colors bgcolor fgcolor diffcolors selectbgcolor |
4ef17537 | 1004 | |
0fba86b3 | 1005 | if {$stuffsaved} return |
df3d83b1 | 1006 | if {![winfo viewable .]} return |
0fba86b3 PM |
1007 | catch { |
1008 | set f [open "~/.gitk-new" w] | |
f0654861 PM |
1009 | puts $f [list set mainfont $mainfont] |
1010 | puts $f [list set textfont $textfont] | |
4840be66 | 1011 | puts $f [list set uifont $uifont] |
7e12f1a6 | 1012 | puts $f [list set tabstop $tabstop] |
f0654861 | 1013 | puts $f [list set findmergefiles $findmergefiles] |
8d858d1a | 1014 | puts $f [list set maxgraphpct $maxgraphpct] |
04c13d38 | 1015 | puts $f [list set maxwidth $maxwidth] |
f8b28a40 | 1016 | puts $f [list set cmitmode $cmitmode] |
f1b86294 | 1017 | puts $f [list set wrapcomment $wrapcomment] |
b8ab2e17 | 1018 | puts $f [list set showneartags $showneartags] |
219ea3a9 | 1019 | puts $f [list set showlocalchanges $showlocalchanges] |
f8a2c0d1 PM |
1020 | puts $f [list set bgcolor $bgcolor] |
1021 | puts $f [list set fgcolor $fgcolor] | |
1022 | puts $f [list set colors $colors] | |
1023 | puts $f [list set diffcolors $diffcolors] | |
60378c0c | 1024 | puts $f [list set selectbgcolor $selectbgcolor] |
e9937d2a | 1025 | |
b6047c5a | 1026 | puts $f "set geometry(main) [wm geometry .]" |
e9937d2a JH |
1027 | puts $f "set geometry(topwidth) [winfo width .tf]" |
1028 | puts $f "set geometry(topheight) [winfo height .tf]" | |
9ca72f4f ML |
1029 | puts $f "set geometry(pwsash0) \"[.tf.histframe.pwclist sash coord 0]\"" |
1030 | puts $f "set geometry(pwsash1) \"[.tf.histframe.pwclist sash coord 1]\"" | |
e9937d2a JH |
1031 | puts $f "set geometry(botwidth) [winfo width .bleft]" |
1032 | puts $f "set geometry(botheight) [winfo height .bleft]" | |
1033 | ||
a90a6d24 PM |
1034 | puts -nonewline $f "set permviews {" |
1035 | for {set v 0} {$v < $nextviewnum} {incr v} { | |
1036 | if {$viewperm($v)} { | |
098dd8a3 | 1037 | puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v)]}" |
a90a6d24 PM |
1038 | } |
1039 | } | |
1040 | puts $f "}" | |
0fba86b3 PM |
1041 | close $f |
1042 | file rename -force "~/.gitk-new" "~/.gitk" | |
1043 | } | |
1044 | set stuffsaved 1 | |
1db95b00 PM |
1045 | } |
1046 | ||
43bddeb4 PM |
1047 | proc resizeclistpanes {win w} { |
1048 | global oldwidth | |
418c4c7b | 1049 | if {[info exists oldwidth($win)]} { |
43bddeb4 PM |
1050 | set s0 [$win sash coord 0] |
1051 | set s1 [$win sash coord 1] | |
1052 | if {$w < 60} { | |
1053 | set sash0 [expr {int($w/2 - 2)}] | |
1054 | set sash1 [expr {int($w*5/6 - 2)}] | |
1055 | } else { | |
1056 | set factor [expr {1.0 * $w / $oldwidth($win)}] | |
1057 | set sash0 [expr {int($factor * [lindex $s0 0])}] | |
1058 | set sash1 [expr {int($factor * [lindex $s1 0])}] | |
1059 | if {$sash0 < 30} { | |
1060 | set sash0 30 | |
1061 | } | |
1062 | if {$sash1 < $sash0 + 20} { | |
2ed49d54 | 1063 | set sash1 [expr {$sash0 + 20}] |
43bddeb4 PM |
1064 | } |
1065 | if {$sash1 > $w - 10} { | |
2ed49d54 | 1066 | set sash1 [expr {$w - 10}] |
43bddeb4 | 1067 | if {$sash0 > $sash1 - 20} { |
2ed49d54 | 1068 | set sash0 [expr {$sash1 - 20}] |
43bddeb4 PM |
1069 | } |
1070 | } | |
1071 | } | |
1072 | $win sash place 0 $sash0 [lindex $s0 1] | |
1073 | $win sash place 1 $sash1 [lindex $s1 1] | |
1074 | } | |
1075 | set oldwidth($win) $w | |
1076 | } | |
1077 | ||
1078 | proc resizecdetpanes {win w} { | |
1079 | global oldwidth | |
418c4c7b | 1080 | if {[info exists oldwidth($win)]} { |
43bddeb4 PM |
1081 | set s0 [$win sash coord 0] |
1082 | if {$w < 60} { | |
1083 | set sash0 [expr {int($w*3/4 - 2)}] | |
1084 | } else { | |
1085 | set factor [expr {1.0 * $w / $oldwidth($win)}] | |
1086 | set sash0 [expr {int($factor * [lindex $s0 0])}] | |
1087 | if {$sash0 < 45} { | |
1088 | set sash0 45 | |
1089 | } | |
1090 | if {$sash0 > $w - 15} { | |
2ed49d54 | 1091 | set sash0 [expr {$w - 15}] |
43bddeb4 PM |
1092 | } |
1093 | } | |
1094 | $win sash place 0 $sash0 [lindex $s0 1] | |
1095 | } | |
1096 | set oldwidth($win) $w | |
1097 | } | |
1098 | ||
b5721c72 PM |
1099 | proc allcanvs args { |
1100 | global canv canv2 canv3 | |
1101 | eval $canv $args | |
1102 | eval $canv2 $args | |
1103 | eval $canv3 $args | |
1104 | } | |
1105 | ||
1106 | proc bindall {event action} { | |
1107 | global canv canv2 canv3 | |
1108 | bind $canv $event $action | |
1109 | bind $canv2 $event $action | |
1110 | bind $canv3 $event $action | |
1111 | } | |
1112 | ||
9a40c50c | 1113 | proc about {} { |
d59c4b6f | 1114 | global uifont |
9a40c50c PM |
1115 | set w .about |
1116 | if {[winfo exists $w]} { | |
1117 | raise $w | |
1118 | return | |
1119 | } | |
1120 | toplevel $w | |
1121 | wm title $w "About gitk" | |
1122 | message $w.m -text { | |
9f1afe05 | 1123 | Gitk - a commit viewer for git |
9a40c50c | 1124 | |
9f1afe05 | 1125 |