1
# Copyright (C) 2005-2010 Canonical Ltd
1
# Copyright (C) 2005-2011 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
49
47
from bzrlib.lazy_import import lazy_import
50
48
lazy_import(globals(), """
53
49
from bzrlib import (
60
from bzrlib.symbol_versioning import (
67
57
_valid_boolean_strings = dict(yes=True, no=False,
93
class ConfirmationUserInterfacePolicy(object):
94
"""Wrapper for a UIFactory that allows or denies all confirmed actions."""
96
def __init__(self, wrapped_ui, default_answer, specific_answers):
97
"""Generate a proxy UI that does no confirmations.
99
:param wrapped_ui: Underlying UIFactory.
100
:param default_answer: Bool for whether requests for
101
confirmation from the user should be noninteractively accepted or
103
:param specific_answers: Map from confirmation_id to bool answer.
105
self.wrapped_ui = wrapped_ui
106
self.default_answer = default_answer
107
self.specific_answers = specific_answers
109
def __getattr__(self, name):
110
return getattr(self.wrapped_ui, name)
113
return '%s(%r, %r, %r)' % (
114
self.__class__.__name__,
117
self.specific_answers)
119
def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
120
if confirmation_id in self.specific_answers:
121
return self.specific_answers[confirmation_id]
122
elif self.default_answer is not None:
123
return self.default_answer
125
return self.wrapped_ui.confirm_action(
126
prompt, confirmation_id, prompt_kwargs)
103
129
class UIFactory(object):
104
130
"""UI abstraction.
106
132
This tells the library how to display things to the user. Through this
107
133
layer different applications can choose the style of UI.
135
UI Factories are also context managers, for some syntactic sugar some users
109
138
:ivar suppressed_warnings: Identifiers for user warnings that should
115
144
"%(from_format)s to %(to_format)s.\n"
116
145
"This may take some time. Upgrade the repositories to the "
117
146
"same format for better performance."
148
recommend_upgrade=("%(current_format_name)s is deprecated "
149
"and a better format is available.\n"
150
"It is recommended that you upgrade by "
151
"running the command\n"
152
" bzr upgrade %(basedir)s"),
121
155
def __init__(self):
123
157
self.suppressed_warnings = set()
124
158
self._quiet = False
161
"""Context manager entry support.
163
Override in a concrete factory class if initialisation before use is
166
return self # This is bound to the 'as' clause in a with statement.
168
def __exit__(self, exc_type, exc_val, exc_tb):
169
"""Context manager exit support.
171
Override in a concrete factory class if more cleanup than a simple
172
self.clear_term() is needed when the UIFactory is finished with.
175
return False # propogate exceptions.
126
177
def be_quiet(self, state):
127
178
"""Tell the UI to be more quiet, or not.
132
183
self._quiet = state
185
def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
186
"""Seek user confirmation for an action.
188
If the UI is noninteractive, or the user does not want to be asked
189
about this action, True is returned, indicating bzr should just
192
The confirmation id allows the user to configure certain actions to
193
always be confirmed or always denied, and for UIs to specialize the
194
display of particular confirmations.
196
:param prompt: Suggested text to display to the user.
197
:param prompt_kwargs: A dictionary of arguments that can be
198
string-interpolated into the prompt.
199
:param confirmation_id: Unique string identifier for the confirmation.
201
return self.get_boolean(prompt % prompt_kwargs)
134
203
def get_password(self, prompt='', **kwargs):
135
204
"""Prompt the user for a password.
158
227
version of stdout, but in a GUI it might be appropriate to send it to a
159
228
window displaying the text.
161
:param encoding: Unicode encoding for output; default is the
162
terminal encoding, which may be different from the user encoding.
230
:param encoding: Unicode encoding for output; if not specified
231
uses the configured 'output_encoding' if any; otherwise the
163
233
(See get_terminal_encoding.)
165
235
:param encoding_type: How to handle encoding errors:
168
238
# XXX: is the caller supposed to close the resulting object?
169
239
if encoding is None:
170
encoding = osutils.get_terminal_encoding()
240
from bzrlib import config
241
encoding = config.GlobalConfig().get_user_option(
244
encoding = osutils.get_terminal_encoding(trace=True)
171
245
if encoding_type is None:
172
246
encoding_type = 'replace'
173
247
out_stream = self._make_output_stream_explicit(encoding, encoding_type)
265
339
return NullProgressView()
267
def recommend_upgrade(self,
270
# XXX: this should perhaps be in the TextUIFactory and the default can do
273
# XXX: Change to show_user_warning - that will accomplish the previous
274
# xxx. -- mbp 2010-02-25
275
trace.warning("%s is deprecated "
276
"and a better format is available.\n"
277
"It is recommended that you upgrade by "
278
"running the command\n"
341
def recommend_upgrade(self, current_format_name, basedir):
342
"""Recommend the user upgrade a control directory.
344
:param current_format_name: Description of the current format
345
:param basedir: Location of the control dir
347
self.show_user_warning('recommend_upgrade',
348
current_format_name=current_format_name, basedir=basedir)
283
350
def report_transport_activity(self, transport, byte_count, direction):
284
351
"""Called by transports as they do IO.
352
419
"without an upgrade path.\n" % (inter.target._format,))
356
class SilentUIFactory(UIFactory):
422
class NoninteractiveUIFactory(UIFactory):
423
"""Base class for UIs with no user."""
425
def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
429
return '%s()' % (self.__class__.__name__, )
432
class SilentUIFactory(NoninteractiveUIFactory):
357
433
"""A UI Factory which never prints anything.
359
435
This is the default UI, if another one is never registered by a program
394
470
def __repr__(self):
395
471
return "%s(%r)" % (self.__class__.__name__, self.responses)
473
def confirm_action(self, prompt, confirmation_id, args):
474
return self.get_boolean(prompt % args)
397
476
def get_boolean(self, prompt):
398
477
return self.responses.pop(0)