]> git.ipfire.org Git - thirdparty/git.git/blame - gitk
gitk: Factored out some common code into a new start_rev_list procedure
[thirdparty/git.git] / gitk
CommitLineData
1db95b00
PM
1#!/bin/sh
2# Tcl ignores the next line -*- tcl -*- \
9e026d39 3exec wish "$0" -- "$@"
1db95b00
PM
4
5# Copyright (C) 2005 Paul Mackerras. All rights reserved.
6# This program is free software; it may be used, copied, modified
7# and distributed under the terms of the GNU General Public Licence,
8# either version 2, or (at your option) any later version.
9
73b6a6cb
JH
10proc gitdir {} {
11 global env
12 if {[info exists env(GIT_DIR)]} {
13 return $env(GIT_DIR)
14 } else {
15 return ".git"
16 }
17}
18
b5c2f306
SV
19proc parse_args {rargs} {
20 global parsed_args
21
22 if [catch {
23 set parse_args [concat --default HEAD $rargs]
24 set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
25 }] {
26 # if git-rev-parse failed for some reason...
27 if {$rargs == {}} {
28 set rargs HEAD
29 }
30 set parsed_args $rargs
31 }
32 return $parsed_args
33}
34
38ad0910 35proc start_rev_list {rlargs} {
466e4fdd 36 global startmsecs nextupdate ncmupdate
38ad0910 37 global commfd leftover gitencoding
9ccbdfbf 38
9ccbdfbf 39 set startmsecs [clock clicks -milliseconds]
2ed49d54 40 set nextupdate [expr {$startmsecs + 100}]
b664550c 41 set ncmupdate 1
2efef4b9 42 if [catch {
38ad0910
PM
43 set commfd [open [concat | git-rev-list --header --topo-order \
44 --parents $rlargs] r]
2efef4b9 45 } err] {
cfb4563c 46 puts stderr "Error executing git-rev-list: $err"
1d10f36d
PM
47 exit 1
48 }
b490a991 49 set leftover {}
495473c0 50 fconfigure $commfd -blocking 0 -translation lf -encoding $gitencoding
466e4fdd 51 fileevent $commfd readable [list getcommitlines $commfd]
38ad0910
PM
52 . config -cursor watch
53 settextcursor watch
54}
55
56proc getcommits {rargs} {
57 global oldcommits commits phase canv mainfont env
58
59 # check that we can find a .git directory somewhere...
60 set gitdir [gitdir]
61 if {![file isdirectory $gitdir]} {
62 error_popup "Cannot find the git directory \"$gitdir\"."
63 exit 1
64 }
65 set oldcommits {}
66 set commits {}
67 set phase getcommits
68 start_rev_list [parse_args $rargs]
1d10f36d
PM
69 $canv delete all
70 $canv create text 3 3 -anchor nw -text "Reading commits..." \
71 -font $mainfont -tags textitems
72}
73
b490a991 74proc getcommitlines {commfd} {
b5c2f306 75 global oldcommits commits parents cdate children nchildren
232475d3 76 global commitlisted phase nextupdate
b490a991 77 global stopped redisplaying leftover
b5c2f306 78 global canv
9ccbdfbf 79
b490a991
PM
80 set stuff [read $commfd]
81 if {$stuff == {}} {
1d10f36d 82 if {![eof $commfd]} return
f0654861 83 # set it blocking so we wait for the process to terminate
df3d83b1 84 fconfigure $commfd -blocking 1
1d10f36d 85 if {![catch {close $commfd} err]} {
9ccbdfbf 86 after idle finishcommits
1d10f36d
PM
87 return
88 }
9a40c50c 89 if {[string range $err 0 4] == "usage"} {
9ccbdfbf 90 set err \
2ed49d54
JH
91 "Gitk: error reading commits: bad arguments to git-rev-list.\
92 (Note: arguments to gitk are passed to git-rev-list\
93 to allow selection of commits to be displayed.)"
9a40c50c 94 } else {
df3d83b1 95 set err "Error reading commits: $err"
9a40c50c 96 }
df3d83b1 97 error_popup $err
1d10f36d 98 exit 1
9a40c50c 99 }
b490a991
PM
100 set start 0
101 while 1 {
102 set i [string first "\0" $stuff $start]
103 if {$i < 0} {
7e952e79 104 append leftover [string range $stuff $start end]
b490a991 105 return
9ccbdfbf 106 }
b490a991
PM
107 set cmit [string range $stuff $start [expr {$i - 1}]]
108 if {$start == 0} {
109 set cmit "$leftover$cmit"
7e952e79 110 set leftover {}
b490a991
PM
111 }
112 set start [expr {$i + 1}]
e5ea701b
PM
113 set j [string first "\n" $cmit]
114 set ok 0
115 if {$j >= 0} {
116 set ids [string range $cmit 0 [expr {$j - 1}]]
117 set ok 1
118 foreach id $ids {
119 if {![regexp {^[0-9a-f]{40}$} $id]} {
120 set ok 0
121 break
122 }
123 }
124 }
125 if {!$ok} {
7e952e79
PM
126 set shortcmit $cmit
127 if {[string length $shortcmit] > 80} {
128 set shortcmit "[string range $shortcmit 0 80]..."
129 }
130 error_popup "Can't parse git-rev-list output: {$shortcmit}"
b490a991
PM
131 exit 1
132 }
e5ea701b
PM
133 set id [lindex $ids 0]
134 set olds [lrange $ids 1 end]
135 set cmit [string range $cmit [expr {$j + 1}] end]
b5c2f306
SV
136 if {$phase == "updatecommits"} {
137 $canv delete all
138 set oldcommits $commits
139 set commits {}
140 unset children
141 unset nchildren
142 set phase getcommits
143 }
b490a991
PM
144 lappend commits $id
145 set commitlisted($id) 1
e5ea701b 146 parsecommit $id $cmit 1 [lrange $ids 1 end]
b5c2f306 147 drawcommit $id 1
b664550c
PM
148 if {[clock clicks -milliseconds] >= $nextupdate} {
149 doupdate 1
b490a991
PM
150 }
151 while {$redisplaying} {
152 set redisplaying 0
153 if {$stopped == 1} {
154 set stopped 0
155 set phase "getcommits"
156 foreach id $commits {
b5c2f306 157 drawcommit $id 1
b490a991 158 if {$stopped} break
b664550c
PM
159 if {[clock clicks -milliseconds] >= $nextupdate} {
160 doupdate 1
b490a991 161 }
9ccbdfbf
PM
162 }
163 }
164 }
165 }
166}
167
b664550c
PM
168proc doupdate {reading} {
169 global commfd nextupdate numcommits ncmupdate
9ccbdfbf 170
b664550c
PM
171 if {$reading} {
172 fileevent $commfd readable {}
173 }
9ccbdfbf 174 update
b664550c
PM
175 set nextupdate [expr {[clock clicks -milliseconds] + 100}]
176 if {$numcommits < 100} {
177 set ncmupdate [expr {$numcommits + 1}]
178 } elseif {$numcommits < 10000} {
179 set ncmupdate [expr {$numcommits + 10}]
180 } else {
181 set ncmupdate [expr {$numcommits + 100}]
182 }
183 if {$reading} {
184 fileevent $commfd readable [list getcommitlines $commfd]
185 }
1db95b00
PM
186}
187
188proc readcommit {id} {
b490a991 189 if [catch {set contents [exec git-cat-file commit $id]}] return
e5ea701b 190 parsecommit $id $contents 0 {}
b490a991
PM
191}
192
b5c2f306
SV
193proc updatechildren {id olds} {
194 global children nchildren parents nparents ncleft
9ccbdfbf 195
cfb4563c
PM
196 if {![info exists nchildren($id)]} {
197 set children($id) {}
198 set nchildren($id) 0
9ccbdfbf 199 set ncleft($id) 0
cfb4563c 200 }
e5ea701b
PM
201 set parents($id) $olds
202 set nparents($id) [llength $olds]
203 foreach p $olds {
204 if {![info exists nchildren($p)]} {
205 set children($p) [list $id]
206 set nchildren($p) 1
207 set ncleft($p) 1
208 } elseif {[lsearch -exact $children($p) $id] < 0} {
209 lappend children($p) $id
210 incr nchildren($p)
211 incr ncleft($p)
244edd12
PM
212 }
213 }
b5c2f306
SV
214}
215
216proc parsecommit {id contents listed olds} {
217 global commitinfo cdate
218
219 set inhdr 1
220 set comment {}
221 set headline {}
222 set auname {}
223 set audate {}
224 set comname {}
225 set comdate {}
226 updatechildren $id $olds
232475d3
PM
227 set hdrend [string first "\n\n" $contents]
228 if {$hdrend < 0} {
229 # should never happen...
230 set hdrend [string length $contents]
231 }
232 set header [string range $contents 0 [expr {$hdrend - 1}]]
233 set comment [string range $contents [expr {$hdrend + 2}] end]
234 foreach line [split $header "\n"] {
235 set tag [lindex $line 0]
236 if {$tag == "author"} {
237 set audate [lindex $line end-1]
238 set auname [lrange $line 1 end-2]
239 } elseif {$tag == "committer"} {
240 set comdate [lindex $line end-1]
241 set comname [lrange $line 1 end-2]
1db95b00
PM
242 }
243 }
232475d3
PM
244 set headline {}
245 # take the first line of the comment as the headline
246 set i [string first "\n" $comment]
247 if {$i >= 0} {
248 set headline [string trim [string range $comment 0 $i]]
f6e2869f
PM
249 } else {
250 set headline $comment
232475d3
PM
251 }
252 if {!$listed} {
253 # git-rev-list indents the comment by 4 spaces;
254 # if we got this via git-cat-file, add the indentation
255 set newcomment {}
256 foreach line [split $comment "\n"] {
257 append newcomment " "
258 append newcomment $line
f6e2869f 259 append newcomment "\n"
232475d3
PM
260 }
261 set comment $newcomment
1db95b00
PM
262 }
263 if {$comdate != {}} {
cfb4563c 264 set cdate($id) $comdate
1db95b00 265 }
e5c2d856
PM
266 set commitinfo($id) [list $headline $auname $audate \
267 $comname $comdate $comment]
1db95b00
PM
268}
269
887fe3c4 270proc readrefs {} {
106288cb 271 global tagids idtags headids idheads tagcontents
36a7cad6 272 global otherrefids idotherrefs
106288cb 273
b5c2f306
SV
274 foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
275 catch {unset $v}
276 }
36a7cad6
JH
277 set refd [open [list | git-ls-remote [gitdir]] r]
278 while {0 <= [set n [gets $refd line]]} {
279 if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \
280 match id path]} {
281 continue
c2f6a022 282 }
36a7cad6
JH
283 if {![regexp {^(tags|heads)/(.*)$} $path match type name]} {
284 set type others
285 set name $path
887fe3c4 286 }
36a7cad6
JH
287 if {$type == "tags"} {
288 set tagids($name) $id
289 lappend idtags($id) $name
290 set obj {}
291 set type {}
292 set tag {}
293 catch {
294 set commit [exec git-rev-parse "$id^0"]
295 if {"$commit" != "$id"} {
296 set tagids($name) $commit
297 lappend idtags($commit) $name
298 }
299 }
300 catch {
301 set tagcontents($name) [exec git-cat-file tag "$id"]
f1d83ba3 302 }
36a7cad6
JH
303 } elseif { $type == "heads" } {
304 set headids($name) $id
305 lappend idheads($id) $name
306 } else {
307 set otherrefids($name) $id
308 lappend idotherrefs($id) $name
f1d83ba3
PM
309 }
310 }
36a7cad6 311 close $refd
887fe3c4
PM
312}
313
df3d83b1
PM
314proc error_popup msg {
315 set w .error
316 toplevel $w
317 wm transient $w .
318 message $w.m -text $msg -justify center -aspect 400
319 pack $w.m -side top -fill x -padx 20 -pady 20
320 button $w.ok -text OK -command "destroy $w"
321 pack $w.ok -side bottom -fill x
322 bind $w <Visibility> "grab $w; focus $w"
323 tkwait window $w
324}
325
b5c2f306 326proc makewindow {rargs} {
e5c2d856 327 global canv canv2 canv3 linespc charspc ctext cflist textfont
b74fd579 328 global findtype findtypemenu findloc findstring fstring geometry
887fe3c4 329 global entries sha1entry sha1string sha1but
94a2eede 330 global maincursor textcursor curtextcursor
712fcc08 331 global rowctxmenu mergemax
9a40c50c
PM
332
333 menu .bar
334 .bar add cascade -label "File" -menu .bar.file
335 menu .bar.file
b5c2f306 336 .bar.file add command -label "Update" -command [list updatecommits $rargs]
f1d83ba3 337 .bar.file add command -label "Reread references" -command rereadrefs
1d10f36d 338 .bar.file add command -label "Quit" -command doquit
712fcc08
PM
339 menu .bar.edit
340 .bar add cascade -label "Edit" -menu .bar.edit
341 .bar.edit add command -label "Preferences" -command doprefs
9a40c50c
PM
342 menu .bar.help
343 .bar add cascade -label "Help" -menu .bar.help
344 .bar.help add command -label "About gitk" -command about
345 . configure -menu .bar
346
0fba86b3 347 if {![info exists geometry(canv1)]} {
2ed49d54
JH
348 set geometry(canv1) [expr {45 * $charspc}]
349 set geometry(canv2) [expr {30 * $charspc}]
350 set geometry(canv3) [expr {15 * $charspc}]
351 set geometry(canvh) [expr {25 * $linespc + 4}]
0fba86b3
PM
352 set geometry(ctextw) 80
353 set geometry(ctexth) 30
354 set geometry(cflistw) 30
355 }
0327d27a 356 panedwindow .ctop -orient vertical
0fba86b3
PM
357 if {[info exists geometry(width)]} {
358 .ctop conf -width $geometry(width) -height $geometry(height)
17386066
PM
359 set texth [expr {$geometry(height) - $geometry(canvh) - 56}]
360 set geometry(ctexth) [expr {($texth - 8) /
361 [font metrics $textfont -linespace]}]
0fba86b3 362 }
98f350e5
PM
363 frame .ctop.top
364 frame .ctop.top.bar
365 pack .ctop.top.bar -side bottom -fill x
366 set cscroll .ctop.top.csb
367 scrollbar $cscroll -command {allcanvs yview} -highlightthickness 0
368 pack $cscroll -side right -fill y
369 panedwindow .ctop.top.clist -orient horizontal -sashpad 0 -handlesize 4
370 pack .ctop.top.clist -side top -fill both -expand 1
371 .ctop add .ctop.top
372 set canv .ctop.top.clist.canv
0fba86b3 373 canvas $canv -height $geometry(canvh) -width $geometry(canv1) \
b5721c72
PM
374 -bg white -bd 0 \
375 -yscrollincr $linespc -yscrollcommand "$cscroll set"
98f350e5
PM
376 .ctop.top.clist add $canv
377 set canv2 .ctop.top.clist.canv2
0fba86b3 378 canvas $canv2 -height $geometry(canvh) -width $geometry(canv2) \
b5721c72 379 -bg white -bd 0 -yscrollincr $linespc
98f350e5
PM
380 .ctop.top.clist add $canv2
381 set canv3 .ctop.top.clist.canv3
0fba86b3 382 canvas $canv3 -height $geometry(canvh) -width $geometry(canv3) \
b5721c72 383 -bg white -bd 0 -yscrollincr $linespc
98f350e5 384 .ctop.top.clist add $canv3
43bddeb4 385 bind .ctop.top.clist <Configure> {resizeclistpanes %W %w}
98f350e5
PM
386
387 set sha1entry .ctop.top.bar.sha1
887fe3c4
PM
388 set entries $sha1entry
389 set sha1but .ctop.top.bar.sha1label
390 button $sha1but -text "SHA1 ID: " -state disabled -relief flat \
391 -command gotocommit -width 8
392 $sha1but conf -disabledforeground [$sha1but cget -foreground]
98f350e5 393 pack .ctop.top.bar.sha1label -side left
887fe3c4
PM
394 entry $sha1entry -width 40 -font $textfont -textvariable sha1string
395 trace add variable sha1string write sha1change
98f350e5 396 pack $sha1entry -side left -pady 2
d698206c
PM
397
398 image create bitmap bm-left -data {
399 #define left_width 16
400 #define left_height 16
401 static unsigned char left_bits[] = {
402 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00,
403 0x0e, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x0e, 0x00, 0x1c, 0x00,
404 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x01};
405 }
406 image create bitmap bm-right -data {
407 #define right_width 16
408 #define right_height 16
409 static unsigned char right_bits[] = {
410 0x00, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c,
411 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c,
412 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01};
413 }
414 button .ctop.top.bar.leftbut -image bm-left -command goback \
415 -state disabled -width 26
416 pack .ctop.top.bar.leftbut -side left -fill y
417 button .ctop.top.bar.rightbut -image bm-right -command goforw \
418 -state disabled -width 26
419 pack .ctop.top.bar.rightbut -side left -fill y
420
98f350e5
PM
421 button .ctop.top.bar.findbut -text "Find" -command dofind
422 pack .ctop.top.bar.findbut -side left
423 set findstring {}
df3d83b1 424 set fstring .ctop.top.bar.findstring
887fe3c4 425 lappend entries $fstring
df3d83b1 426 entry $fstring -width 30 -font $textfont -textvariable findstring
df3d83b1 427 pack $fstring -side left -expand 1 -fill x
98f350e5 428 set findtype Exact
b74fd579
PM
429 set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \
430 findtype Exact IgnCase Regexp]
98f350e5
PM
431 set findloc "All fields"
432 tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \
b74fd579 433 Comments Author Committer Files Pickaxe
98f350e5
PM
434 pack .ctop.top.bar.findloc -side right
435 pack .ctop.top.bar.findtype -side right
b74fd579
PM
436 # for making sure type==Exact whenever loc==Pickaxe
437 trace add variable findloc write findlocchange
b5721c72 438
5ad588de
PM
439 panedwindow .ctop.cdet -orient horizontal
440 .ctop add .ctop.cdet
d2610d11
PM
441 frame .ctop.cdet.left
442 set ctext .ctop.cdet.left.ctext
0fba86b3
PM
443 text $ctext -bg white -state disabled -font $textfont \
444 -width $geometry(ctextw) -height $geometry(ctexth) \
b1ba39e7 445 -yscrollcommand ".ctop.cdet.left.sb set" -wrap none
d2610d11
PM
446 scrollbar .ctop.cdet.left.sb -command "$ctext yview"
447 pack .ctop.cdet.left.sb -side right -fill y
448 pack $ctext -side left -fill both -expand 1
449 .ctop.cdet add .ctop.cdet.left
450
f0654861 451 $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
712fcc08
PM
452 $ctext tag conf hunksep -fore blue
453 $ctext tag conf d0 -fore red
454 $ctext tag conf d1 -fore "#00a000"
455 $ctext tag conf m0 -fore red
456 $ctext tag conf m1 -fore blue
457 $ctext tag conf m2 -fore green
458 $ctext tag conf m3 -fore purple
459 $ctext tag conf m4 -fore brown
460 $ctext tag conf mmax -fore darkgrey
461 set mergemax 5
462 $ctext tag conf mresult -font [concat $textfont bold]
463 $ctext tag conf msep -font [concat $textfont bold]
464 $ctext tag conf found -back yellow
e5c2d856 465
d2610d11
PM
466 frame .ctop.cdet.right
467 set cflist .ctop.cdet.right.cfiles
17386066 468 listbox $cflist -bg white -selectmode extended -width $geometry(cflistw) \
d2610d11
PM
469 -yscrollcommand ".ctop.cdet.right.sb set"
470 scrollbar .ctop.cdet.right.sb -command "$cflist yview"
471 pack .ctop.cdet.right.sb -side right -fill y
472 pack $cflist -side left -fill both -expand 1
473 .ctop.cdet add .ctop.cdet.right
0fba86b3 474 bind .ctop.cdet <Configure> {resizecdetpanes %W %w}
d2610d11 475
0327d27a 476 pack .ctop -side top -fill both -expand 1
1db95b00 477
c8dfbcf9
PM
478 bindall <1> {selcanvline %W %x %y}
479 #bindall <B1-Motion> {selcanvline %W %x %y}
cfb4563c
PM
480 bindall <ButtonRelease-4> "allcanvs yview scroll -5 units"
481 bindall <ButtonRelease-5> "allcanvs yview scroll 5 units"
b5721c72
PM
482 bindall <2> "allcanvs scan mark 0 %y"
483 bindall <B2-Motion> "allcanvs scan dragto 0 %y"
17386066
PM
484 bind . <Key-Up> "selnextline -1"
485 bind . <Key-Down> "selnextline 1"
6e2dda35
RS
486 bind . <Key-Right> "goforw"
487 bind . <Key-Left> "goback"
cfb4563c
PM
488 bind . <Key-Prior> "allcanvs yview scroll -1 pages"
489 bind . <Key-Next> "allcanvs yview scroll 1 pages"
490 bindkey <Key-Delete> "$ctext yview scroll -1 pages"
491 bindkey <Key-BackSpace> "$ctext yview scroll -1 pages"
492 bindkey <Key-space> "$ctext yview scroll 1 pages"
df3d83b1
PM
493 bindkey p "selnextline -1"
494 bindkey n "selnextline 1"
6e2dda35
RS
495 bindkey z "goback"
496 bindkey x "goforw"
497 bindkey i "selnextline -1"
498 bindkey k "selnextline 1"
499 bindkey j "goback"
500 bindkey l "goforw"
cfb4563c
PM
501 bindkey b "$ctext yview scroll -1 pages"
502 bindkey d "$ctext yview scroll 18 units"
503 bindkey u "$ctext yview scroll -18 units"
b74fd579
PM
504 bindkey / {findnext 1}
505 bindkey <Key-Return> {findnext 0}
df3d83b1 506 bindkey ? findprev
39ad8570 507 bindkey f nextfile
1d10f36d 508 bind . <Control-q> doquit
98f350e5 509 bind . <Control-f> dofind
b74fd579 510 bind . <Control-g> {findnext 0}
98f350e5 511 bind . <Control-r> findprev
1d10f36d
PM
512 bind . <Control-equal> {incrfont 1}
513 bind . <Control-KP_Add> {incrfont 1}
514 bind . <Control-minus> {incrfont -1}
515 bind . <Control-KP_Subtract> {incrfont -1}
e5c2d856 516 bind $cflist <<ListboxSelect>> listboxsel
0fba86b3 517 bind . <Destroy> {savestuff %W}
df3d83b1 518 bind . <Button-1> "click %W"
17386066 519 bind $fstring <Key-Return> dofind
887fe3c4 520 bind $sha1entry <Key-Return> gotocommit
ee3dc72e 521 bind $sha1entry <<PasteSelection>> clearsha1
ea13cba1
PM
522
523 set maincursor [. cget -cursor]
524 set textcursor [$ctext cget -cursor]
94a2eede 525 set curtextcursor $textcursor
84ba7345 526
c8dfbcf9
PM
527 set rowctxmenu .rowctxmenu
528 menu $rowctxmenu -tearoff 0
529 $rowctxmenu add command -label "Diff this -> selected" \
530 -command {diffvssel 0}
531 $rowctxmenu add command -label "Diff selected -> this" \
532 -command {diffvssel 1}
74daedb6 533 $rowctxmenu add command -label "Make patch" -command mkpatch
bdbfbe3d 534 $rowctxmenu add command -label "Create tag" -command mktag
4a2139f5 535 $rowctxmenu add command -label "Write commit to file" -command writecommit
df3d83b1
PM
536}
537
538# when we make a key binding for the toplevel, make sure
539# it doesn't get triggered when that key is pressed in the
540# find string entry widget.
541proc bindkey {ev script} {
887fe3c4 542 global entries
df3d83b1
PM
543 bind . $ev $script
544 set escript [bind Entry $ev]
545 if {$escript == {}} {
546 set escript [bind Entry <Key>]
547 }
887fe3c4
PM
548 foreach e $entries {
549 bind $e $ev "$escript; break"
550 }
df3d83b1
PM
551}
552
553# set the focus back to the toplevel for any click outside
887fe3c4 554# the entry widgets
df3d83b1 555proc click {w} {
887fe3c4
PM
556 global entries
557 foreach e $entries {
558 if {$w == $e} return
df3d83b1 559 }
887fe3c4 560 focus .
0fba86b3
PM
561}
562
563proc savestuff {w} {
564 global canv canv2 canv3 ctext cflist mainfont textfont
712fcc08 565 global stuffsaved findmergefiles maxgraphpct
04c13d38 566 global maxwidth
4ef17537 567
0fba86b3 568 if {$stuffsaved} return
df3d83b1 569 if {![winfo viewable .]} return
0fba86b3
PM
570 catch {
571 set f [open "~/.gitk-new" w]
f0654861
PM
572 puts $f [list set mainfont $mainfont]
573 puts $f [list set textfont $textfont]
574 puts $f [list set findmergefiles $findmergefiles]
8d858d1a 575 puts $f [list set maxgraphpct $maxgraphpct]
04c13d38 576 puts $f [list set maxwidth $maxwidth]
0fba86b3
PM
577 puts $f "set geometry(width) [winfo width .ctop]"
578 puts $f "set geometry(height) [winfo height .ctop]"
2ed49d54
JH
579 puts $f "set geometry(canv1) [expr {[winfo width $canv]-2}]"
580 puts $f "set geometry(canv2) [expr {[winfo width $canv2]-2}]"
581 puts $f "set geometry(canv3) [expr {[winfo width $canv3]-2}]"
582 puts $f "set geometry(canvh) [expr {[winfo height $canv]-2}]"
0fba86b3
PM
583 set wid [expr {([winfo width $ctext] - 8) \
584 / [font measure $textfont "0"]}]
0fba86b3 585 puts $f "set geometry(ctextw) $wid"
0fba86b3
PM
586 set wid [expr {([winfo width $cflist] - 11) \
587 / [font measure [$cflist cget -font] "0"]}]
588 puts $f "set geometry(cflistw) $wid"
589 close $f
590 file rename -force "~/.gitk-new" "~/.gitk"
591 }
592 set stuffsaved 1
1db95b00
PM
593}
594
43bddeb4
PM
595proc resizeclistpanes {win w} {
596 global oldwidth
597 if [info exists oldwidth($win)] {
598 set s0 [$win sash coord 0]
599 set s1 [$win sash coord 1]
600 if {$w < 60} {
601 set sash0 [expr {int($w/2 - 2)}]
602 set sash1 [expr {int($w*5/6 - 2)}]
603 } else {
604 set factor [expr {1.0 * $w / $oldwidth($win)}]
605 set sash0 [expr {int($factor * [lindex $s0 0])}]
606 set sash1 [expr {int($factor * [lindex $s1 0])}]
607 if {$sash0 < 30} {
608 set sash0 30
609 }
610 if {$sash1 < $sash0 + 20} {
2ed49d54 611 set sash1 [expr {$sash0 + 20}]
43bddeb4
PM
612 }
613 if {$sash1 > $w - 10} {
2ed49d54 614 set sash1 [expr {$w - 10}]
43bddeb4 615 if {$sash0 > $sash1 - 20} {
2ed49d54 616 set sash0 [expr {$sash1 - 20}]
43bddeb4
PM
617 }
618 }
619 }
620 $win sash place 0 $sash0 [lindex $s0 1]
621 $win sash place 1 $sash1 [lindex $s1 1]
622 }
623 set oldwidth($win) $w
624}
625
626proc resizecdetpanes {win w} {
627 global oldwidth
628 if [info exists oldwidth($win)] {
629 set s0 [$win sash coord 0]
630 if {$w < 60} {
631 set sash0 [expr {int($w*3/4 - 2)}]
632 } else {
633 set factor [expr {1.0 * $w / $oldwidth($win)}]
634 set sash0 [expr {int($factor * [lindex $s0 0])}]
635 if {$sash0 < 45} {
636 set sash0 45
637 }
638 if {$sash0 > $w - 15} {
2ed49d54 639 set sash0 [expr {$w - 15}]
43bddeb4
PM
640 }
641 }
642 $win sash place 0 $sash0 [lindex $s0 1]
643 }
644 set oldwidth($win) $w
645}
646
b5721c72
PM
647proc allcanvs args {
648 global canv canv2 canv3
649 eval $canv $args
650 eval $canv2 $args
651 eval $canv3 $args
652}
653
654proc bindall {event action} {
655 global canv canv2 canv3
656 bind $canv $event $action
657 bind $canv2 $event $action
658 bind $canv3 $event $action
659}
660
9a40c50c
PM
661proc about {} {
662 set w .about
663 if {[winfo exists $w]} {
664 raise $w
665 return
666 }
667 toplevel $w
668 wm title $w "About gitk"
669 message $w.m -text {
c8dfbcf9 670Gitk version 1.2
9a40c50c
PM
671
672