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