51
52
"""Create a TextUIFactory.
53
:param bar_type: The type of progress bar to create. Deprecated
54
and ignored; a TextProgressView is always used.
56
54
super(TextUIFactory, self).__init__()
57
55
# TODO: there's no good reason not to pass all three streams, maybe we
150
148
return NullProgressView()
150
def _make_output_stream_explicit(self, encoding, encoding_type):
151
if encoding_type == 'exact':
152
# force sys.stdout to be binary stream on win32;
153
# NB: this leaves the file set in that mode; may cause problems if
154
# one process tries to do binary and then text output
155
if sys.platform == 'win32':
156
fileno = getattr(self.stdout, 'fileno', None)
159
msvcrt.setmode(fileno(), os.O_BINARY)
160
return TextUIOutputStream(self, self.stdout)
162
encoded_stdout = codecs.getwriter(encoding)(self.stdout,
163
errors=encoding_type)
164
# For whatever reason codecs.getwriter() does not advertise its encoding
165
# it just returns the encoding of the wrapped file, which is completely
166
# bogus. So set the attribute, so we can find the correct encoding later.
167
encoded_stdout.encoding = encoding
168
return TextUIOutputStream(self, encoded_stdout)
152
170
def note(self, msg):
153
171
"""Write an already-formatted message, clearing the progress bar if necessary."""
154
172
self.clear_term()
176
194
self._progress_view.show_transport_activity(transport,
177
195
direction, byte_count)
197
def show_error(self, msg):
199
self.stderr.write("bzr: error: %s\n" % msg)
201
def show_message(self, msg):
204
def show_warning(self, msg):
206
self.stderr.write("bzr: warning: %s\n" % msg)
179
208
def _progress_updated(self, task):
180
209
"""A task has been updated and wants to be displayed.
227
256
def _show_line(self, s):
228
257
# sys.stderr.write("progress %r\n" % s)
230
self._term_file.write('\r%-*.*s\r' % (n, n, s))
258
if self._width is not None:
260
s = '%-*.*s' % (n, n, s)
261
self._term_file.write('\r' + s + '\r')
233
264
if self._have_output:
357
388
self._bytes_since_update = 0
358
389
self._last_transport_msg = msg
393
class TextUIOutputStream(object):
394
"""Decorates an output stream so that the terminal is cleared before writing.
396
This is supposed to ensure that the progress bar does not conflict with bulk
399
# XXX: this does not handle the case of writing part of a line, then doing
400
# progress bar output: the progress bar will probably write over it.
401
# one option is just to buffer that text until we have a full line;
402
# another is to save and restore it
404
# XXX: might need to wrap more methods
406
def __init__(self, ui_factory, wrapped_stream):
407
self.ui_factory = ui_factory
408
self.wrapped_stream = wrapped_stream
409
# this does no transcoding, but it must expose the underlying encoding
410
# because some callers need to know what can be written - see for
411
# example unescape_for_display.
412
self.encoding = getattr(wrapped_stream, 'encoding', None)
415
self.ui_factory.clear_term()
416
self.wrapped_stream.flush()
418
def write(self, to_write):
419
self.ui_factory.clear_term()
420
self.wrapped_stream.write(to_write)
422
def writelines(self, lines):
423
self.ui_factory.clear_term()
424
self.wrapped_stream.writelines(lines)