Merge branch 'master' of git://git.kernel.org/pub/scm/gitk/gitk
[git] / git-gui / lib / status_bar.tcl
1 # git-gui status bar mega-widget
2 # Copyright (C) 2007 Shawn Pearce
3
4 class status_bar {
5
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)
13
14 constructor new {path} {
15         set w $path
16         set w_l $w.l
17         set w_c $w.c
18
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
27
28         bind $w <Destroy> [cb _delete %W]
29         return $this
30 }
31
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         }
45
46         set status $msg
47         set prefix $msg
48         set units  $uds
49         set meter  {}
50 }
51
52 method update {have total} {
53         set pdone 0
54         if {$total > 0} {
55                 set pdone [expr {100 * $have / $total}]
56         }
57
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 }
62
63 method update_meter {buf} {
64         append meter $buf
65         set r [string last "\r" $meter]
66         if {$r == -1} {
67                 return
68         }
69
70         set prior [string range $meter 0 $r]
71         set meter [string range $meter [expr {$r + 1}] end]
72         if {[regexp "\\((\\d+)/(\\d+)\\)\\s+done\r\$" $prior _j a b]} {
73                 update $this $a $b
74         }
75 }
76
77 method stop {{msg {}}} {
78         destroy $w_c
79         if {$msg ne {}} {
80                 set status $msg
81         }
82 }
83
84 method show {msg {test {}}} {
85         if {$test eq {} || $status eq $test} {
86                 set status $msg
87         }
88 }
89
90 method _delete {current} {
91         if {$current eq $w} {
92                 delete_this
93         }
94 }
95
96 }