1
# Copyright (C) 2005 Aaron Bentley <aaron.bentley@utoronto.ca>
2
# Copyright (C) 2005, 2006 Canonical Ltd
1
# Copyright (C) 2005, 2006, 2008 Canonical Ltd
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
28
27
bzrlib it really is best to use bzrlib.ui.ui_factory.
31
# TODO: Optionally show elapsed time instead/as well as ETA; nicer
32
# when the rate is unpredictable
38
from bzrlib.lazy_import import lazy_import
39
lazy_import(globals(), """
40
37
from bzrlib import (
45
43
from bzrlib.trace import mutter
65
_progress_bar_types = {}
63
class ProgressTask(object):
64
"""Model component of a progress indicator.
66
Most code that needs to indicate progress should update one of these,
67
and it will in turn update the display, if one is present.
69
Code updating the task may also set fields as hints about how to display
70
it: show_pct, show_spinner, show_eta, show_count, show_bar. UIs
71
will not necessarily respect all these fields.
74
def __init__(self, parent_task=None, ui_factory=None):
75
self._parent_task = parent_task
78
self.current_cnt = None
80
self.ui_factory = ui_factory
82
self.show_spinner = True
83
self.show_eta = False,
84
self.show_count = True
87
def update(self, msg, current_cnt=None, total_cnt=None):
89
self.current_cnt = current_cnt
91
self.total_cnt = total_cnt
92
self.ui_factory.show_progress(self)
98
self.ui_factory.progress_finished(self)
100
def make_sub_task(self):
101
return ProgressTask(self, self.ui_factory)
103
def _overall_completion_fraction(self, child_fraction=0.0):
104
"""Return fractional completion of this task and its parents
106
Returns None if no completion can be computed."""
108
own_fraction = (float(self.current_cnt) + child_fraction) / self.total_cnt
111
if self._parent_task is None:
114
if own_fraction is None:
116
return self._parent_task._overall_completion_fraction(own_fraction)
118
def note(self, fmt_string, *args):
119
"""Record a note without disrupting the progress bar."""
120
# XXX: shouldn't be here; put it in mutter or the ui instead
121
self.ui_factory.note(fmt_string % args)
124
# XXX: shouldn't be here; put it in mutter or the ui instead
125
self.ui_factory.clear_term()
68
128
def ProgressBar(to_file=None, **kwargs):
87
147
_progress_bar_types.keys())
88
148
return _progress_bar_types[requested_bar_type](to_file=to_file, **kwargs)
91
151
class ProgressBarStack(object):
92
152
"""A stack of progress bars."""
147
207
def return_pb(self, bar):
148
208
"""Return bar after its been used."""
149
209
if bar is not self._stack[-1]:
150
raise errors.MissingProgressBarFinish()
210
warnings.warn("%r is not currently active" % (bar,))
154
215
class _BaseProgressBar(object):
225
287
return DummyProgress(**kwargs)
228
_progress_bar_types['dummy'] = DummyProgress
229
_progress_bar_types['none'] = DummyProgress
232
290
class DotsProgressBar(_BaseProgressBar):
234
292
def __init__(self, **kwargs):
331
388
def update(self, msg, current_cnt=None, total_cnt=None,
333
"""Update and redraw progress bar."""
390
"""Update and redraw progress bar.
335
393
msg = self.last_msg
401
462
# make both fields the same size
402
463
t = '%i' % (self.last_total)
403
464
c = '%*i' % (len(t), self.last_cnt)
404
count_str = ' ' + c + '/' + t
465
count_str = ' ' + c + '/' + t
406
467
if self.show_bar:
407
468
# progress bar, if present, soaks up all remaining space
558
619
self.cur_phase += 1
559
620
self.pb.update(self.message, self.cur_phase, self.total)
623
_progress_bar_types = {}
624
_progress_bar_types['dummy'] = DummyProgress
625
_progress_bar_types['none'] = DummyProgress
626
_progress_bar_types['tty'] = TTYProgressBar
627
_progress_bar_types['dots'] = DotsProgressBar