Code

git-gui: Handle progress bars from newer gits
[git.git] / lib / status_bar.tcl
1 # git-gui status bar mega-widget
2 # Copyright (C) 2007 Shawn Pearce
4 class status_bar {
6 field w         ; # our own window path
7 field w_l       ; # text widget we draw messages into
8 field w_c       ; # canvas we draw a progress bar into
9 field status  {}; # single line of text we show
10 field prefix  {}; # text we format into status
11 field units   {}; # unit of progress
12 field meter   {}; # current core git progress meter (if active)
14 constructor new {path} {
15         set w $path
16         set w_l $w.l
17         set w_c $w.c
19         frame $w \
20                 -borderwidth 1 \
21                 -relief sunken
22         label $w_l \
23                 -textvariable @status \
24                 -anchor w \
25                 -justify left
26         pack $w_l -side left
28         bind $w <Destroy> [cb _delete %W]
29         return $this
30 }
32 method start {msg uds} {
33         if {[winfo exists $w_c]} {
34                 $w_c coords bar 0 0 0 20
35         } else {
36                 canvas $w_c \
37                         -width 100 \
38                         -height [expr {int([winfo reqheight $w_l] * 0.6)}] \
39                         -borderwidth 1 \
40                         -relief groove \
41                         -highlightt 0
42                 $w_c create rectangle 0 0 0 20 -tags bar -fill navy
43                 pack $w_c -side right
44         }
46         set status $msg
47         set prefix $msg
48         set units  $uds
49         set meter  {}
50 }
52 method update {have total} {
53         set pdone 0
54         if {$total > 0} {
55                 set pdone [expr {100 * $have / $total}]
56         }
58         set status [format "%s ... %i of %i %s (%2i%%)" \
59                 $prefix $have $total $units $pdone]
60         $w_c coords bar 0 0 $pdone 20
61 }
63 method update_meter {buf} {
64         append meter $buf
65         set r [string last "\r" $meter]
66         if {$r == -1} {
67                 return
68         }
70         set prior [string range $meter 0 $r]
71         set meter [string range $meter [expr {$r + 1}] end]
72         set p "\\((\\d+)/(\\d+)\\)"
73         if {[regexp ":\\s*\\d+% $p\(?:, done.\\s*\n|\\s*\r)\$" $prior _j a b]} {
74                 update $this $a $b
75         } elseif {[regexp "$p\\s+done\r\$" $prior _j a b]} {
76                 update $this $a $b
77         }
78 }
80 method stop {{msg {}}} {
81         destroy $w_c
82         if {$msg ne {}} {
83                 set status $msg
84         }
85 }
87 method show {msg {test {}}} {
88         if {$test eq {} || $status eq $test} {
89                 set status $msg
90         }
91 }
93 method _delete {current} {
94         if {$current eq $w} {
95                 delete_this
96         }
97 }
99 }