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