~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/ui/text.py

  • Committer: John Arbash Meinel
  • Date: 2009-12-10 17:16:19 UTC
  • mfrom: (4884 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4889.
  • Revision ID: john@arbash-meinel.com-20091210171619-ehdcxjbl8afhq9g1
Bring in bzr.dev 4884

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
"""Text UI, write output to the console.
19
19
"""
20
20
 
 
21
import codecs
21
22
import getpass
22
23
import os
23
24
import sys
49
50
                 stdout=None,
50
51
                 stderr=None):
51
52
        """Create a TextUIFactory.
52
 
 
53
 
        :param bar_type: The type of progress bar to create.  Deprecated
54
 
            and ignored; a TextProgressView is always used.
55
53
        """
56
54
        super(TextUIFactory, self).__init__()
57
55
        # TODO: there's no good reason not to pass all three streams, maybe we
149
147
        else:
150
148
            return NullProgressView()
151
149
 
 
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)
 
157
                if fileno:
 
158
                    import msvcrt
 
159
                    msvcrt.setmode(fileno(), os.O_BINARY)
 
160
            return TextUIOutputStream(self, self.stdout)
 
161
        else:
 
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)
 
169
 
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)
178
196
 
 
197
    def show_error(self, msg):
 
198
        self.clear_term()
 
199
        self.stderr.write("bzr: error: %s\n" % msg)
 
200
 
 
201
    def show_message(self, msg):
 
202
        self.note(msg)
 
203
 
 
204
    def show_warning(self, msg):
 
205
        self.clear_term()
 
206
        self.stderr.write("bzr: warning: %s\n" % msg)
 
207
 
179
208
    def _progress_updated(self, task):
180
209
        """A task has been updated and wants to be displayed.
181
210
        """
226
255
 
227
256
    def _show_line(self, s):
228
257
        # sys.stderr.write("progress %r\n" % s)
229
 
        n = self._width - 1
230
 
        self._term_file.write('\r%-*.*s\r' % (n, n, s))
 
258
        if self._width is not None:
 
259
            n = self._width - 1
 
260
            s = '%-*.*s' % (n, n, s)
 
261
        self._term_file.write('\r' + s + '\r')
231
262
 
232
263
    def clear(self):
233
264
        if self._have_output:
357
388
            self._bytes_since_update = 0
358
389
            self._last_transport_msg = msg
359
390
            self._repaint()
 
391
 
 
392
 
 
393
class TextUIOutputStream(object):
 
394
    """Decorates an output stream so that the terminal is cleared before writing.
 
395
 
 
396
    This is supposed to ensure that the progress bar does not conflict with bulk
 
397
    text output.
 
398
    """
 
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
 
403
 
 
404
    # XXX: might need to wrap more methods
 
405
 
 
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)
 
413
 
 
414
    def flush(self):
 
415
        self.ui_factory.clear_term()
 
416
        self.wrapped_stream.flush()
 
417
 
 
418
    def write(self, to_write):
 
419
        self.ui_factory.clear_term()
 
420
        self.wrapped_stream.write(to_write)
 
421
 
 
422
    def writelines(self, lines):
 
423
        self.ui_factory.clear_term()
 
424
        self.wrapped_stream.writelines(lines)