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