git-gui / lib / status_bar.tclon commit Merge branch 'maint' of git://repo.or.cz/git-gui into maint (7468c29)
   1# git-gui status bar mega-widget
   2# Copyright (C) 2007 Shawn Pearce
   3
   4class status_bar {
   5
   6field w         ; # our own window path
   7field w_l       ; # text widget we draw messages into
   8field w_c       ; # canvas we draw a progress bar into
   9field status  {}; # single line of text we show
  10field prefix  {}; # text we format into status
  11field units   {}; # unit of progress
  12field meter   {}; # current core git progress meter (if active)
  13
  14constructor 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
  32method 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
  52method 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
  63method 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        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}
  79
  80method stop {{msg {}}} {
  81        destroy $w_c
  82        if {$msg ne {}} {
  83                set status $msg
  84        }
  85}
  86
  87method show {msg {test {}}} {
  88        if {$test eq {} || $status eq $test} {
  89                set status $msg
  90        }
  91}
  92
  93method _delete {current} {
  94        if {$current eq $w} {
  95                delete_this
  96        }
  97}
  98
  99}