| # git-gui status bar mega-widget | |
| # Copyright (C) 2007 Shawn Pearce | |
| class status_bar { | |
| field w ; # our own window path | |
| field w_l ; # text widget we draw messages into | |
| field w_c ; # canvas we draw a progress bar into | |
| field c_pack ; # script to pack the canvas with | |
| field status {}; # single line of text we show | |
| field prefix {}; # text we format into status | |
| field units {}; # unit of progress | |
| field meter {}; # current core git progress meter (if active) | |
| constructor new {path} { | |
| global use_ttk NS | |
| set w $path | |
| set w_l $w.l | |
| set w_c $w.c | |
| ${NS}::frame $w | |
| if {!$use_ttk} { | |
| $w configure -borderwidth 1 -relief sunken | |
| } | |
| ${NS}::label $w_l \ | |
| -textvariable @status \ | |
| -anchor w \ | |
| -justify left | |
| pack $w_l -side left | |
| set c_pack [cb _oneline_pack] | |
| bind $w <Destroy> [cb _delete %W] | |
| return $this | |
| } | |
| method _oneline_pack {} { | |
| $w_c conf -width 100 | |
| pack $w_c -side right | |
| } | |
| constructor two_line {path} { | |
| global NS | |
| set w $path | |
| set w_l $w.l | |
| set w_c $w.c | |
| ${NS}::frame $w | |
| ${NS}::label $w_l \ | |
| -textvariable @status \ | |
| -anchor w \ | |
| -justify left | |
| pack $w_l -anchor w -fill x | |
| set c_pack [list pack $w_c -fill x] | |
| bind $w <Destroy> [cb _delete %W] | |
| return $this | |
| } | |
| method start {msg uds} { | |
| if {[winfo exists $w_c]} { | |
| $w_c coords bar 0 0 0 20 | |
| } else { | |
| canvas $w_c \ | |
| -height [expr {int([winfo reqheight $w_l] * 0.6)}] \ | |
| -borderwidth 1 \ | |
| -relief groove \ | |
| -highlightt 0 | |
| $w_c create rectangle 0 0 0 20 -tags bar -fill navy | |
| eval $c_pack | |
| } | |
| set status $msg | |
| set prefix $msg | |
| set units $uds | |
| set meter {} | |
| } | |
| method update {have total} { | |
| set pdone 0 | |
| set cdone 0 | |
| if {$total > 0} { | |
| set pdone [expr {100 * $have / $total}] | |
| set cdone [expr {[winfo width $w_c] * $have / $total}] | |
| } | |
| set prec [string length [format %i $total]] | |
| set status [mc "%s ... %*i of %*i %s (%3i%%)" \ | |
| $prefix \ | |
| $prec $have \ | |
| $prec $total \ | |
| $units $pdone] | |
| $w_c coords bar 0 0 $cdone 20 | |
| } | |
| method update_meter {buf} { | |
| append meter $buf | |
| set r [string last "\r" $meter] | |
| if {$r == -1} { | |
| return | |
| } | |
| set prior [string range $meter 0 $r] | |
| set meter [string range $meter [expr {$r + 1}] end] | |
| set p "\\((\\d+)/(\\d+)\\)" | |
| if {[regexp ":\\s*\\d+% $p\(?:, done.\\s*\n|\\s*\r)\$" $prior _j a b]} { | |
| update $this $a $b | |
| } elseif {[regexp "$p\\s+done\r\$" $prior _j a b]} { | |
| update $this $a $b | |
| } | |
| } | |
| method stop {{msg {}}} { | |
| destroy $w_c | |
| if {$msg ne {}} { | |
| set status $msg | |
| } | |
| } | |
| method show {msg {test {}}} { | |
| if {$test eq {} || $status eq $test} { | |
| set status $msg | |
| } | |
| } | |
| method _delete {current} { | |
| if {$current eq $w} { | |
| delete_this | |
| } | |
| } | |
| } |