|  | # 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 | 
|  | 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 | 
|  | } | 
|  | } | 
|  |  | 
|  | } |