1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
  
     | 
    
      # 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
	}
}
}
 
     |