]> git.ipfire.org Git - thirdparty/git.git/blame - gitk
gitk: Fix bug introduced in commit 67a4f1a7
[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
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 112proc 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 125proc 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 134proc 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
259proc 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
292proc 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 297proc 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 320proc 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 377proc 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 391proc 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
445proc 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
458proc 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
467proc 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 481proc 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
491proc 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
498proc 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 515proc 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
938proc 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
955proc 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
966proc 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.
975proc 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 989proc 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
997proc 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
1047proc 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
1078proc 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
1099proc allcanvs args {
1100 global canv canv2 canv3
1101 eval $canv $args
1102 eval $canv2 $args
1103 eval $canv3 $args
1104}
1105
1106proc 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 1113proc 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 1123Gitk - a commit viewer for git
9a40c50c 1124
9f1afe05 1125