Use message module as API for most questions
This commit is contained in:
parent
756564ebff
commit
f0ed43ec20
@ -150,7 +150,7 @@ def ask_for_filename(suggested_filename, win_id, *, parent=None,
|
||||
suggested_filename = utils.force_encoding(suggested_filename, encoding)
|
||||
|
||||
q = usertypes.Question(parent)
|
||||
q.text = "Save file to:"
|
||||
q.title = "Save file to:"
|
||||
q.mode = usertypes.PromptMode.text
|
||||
q.completed.connect(q.deleteLater)
|
||||
q.default = _path_suggestion(suggested_filename)
|
||||
@ -382,20 +382,13 @@ class DownloadItem(QObject):
|
||||
else:
|
||||
self.set_fileobj(fileobj)
|
||||
|
||||
def _ask_confirm_question(self, msg):
|
||||
def _ask_confirm_question(self, title, msg):
|
||||
"""Create a Question object to be asked."""
|
||||
q = usertypes.Question(self)
|
||||
q.text = msg
|
||||
q.mode = usertypes.PromptMode.yesno
|
||||
q.answered_yes.connect(self._create_fileobj)
|
||||
q.answered_no.connect(functools.partial(self.cancel,
|
||||
remove_data=False))
|
||||
q.cancelled.connect(functools.partial(self.cancel, remove_data=False))
|
||||
self.cancelled.connect(q.abort)
|
||||
self.error.connect(q.abort)
|
||||
message_bridge = objreg.get('message-bridge', scope='window',
|
||||
window=self._win_id)
|
||||
message_bridge.ask(q, blocking=False)
|
||||
no_action = functools.partial(self.cancel, remove_data=False)
|
||||
message.confirm_async(self._win_id, title=title, text=msg,
|
||||
yes_action=self._create_fileobj,
|
||||
no_action=no_action, cancel_action=no_action,
|
||||
abort_on=[self.cancelled, self.error])
|
||||
|
||||
def _die(self, msg):
|
||||
"""Abort the download and emit an error."""
|
||||
@ -615,13 +608,13 @@ class DownloadItem(QObject):
|
||||
# The file already exists, so ask the user if it should be
|
||||
# overwritten.
|
||||
txt = self._filename + " already exists. Overwrite?"
|
||||
self._ask_confirm_question(txt)
|
||||
self._ask_confirm_question("Overwrite existing file?", txt)
|
||||
# FIFO, device node, etc. Make sure we want to do this
|
||||
elif (os.path.exists(self._filename) and
|
||||
not os.path.isdir(self._filename)):
|
||||
txt = (self._filename + " already exists and is a special file. "
|
||||
"Write to this?")
|
||||
self._ask_confirm_question(txt)
|
||||
self._ask_confirm_question("Overwrite special file?", txt)
|
||||
else:
|
||||
self._create_fileobj()
|
||||
|
||||
|
@ -220,25 +220,19 @@ class NetworkManager(QNetworkAccessManager):
|
||||
Return:
|
||||
The answer the user gave or None if the prompt was cancelled.
|
||||
"""
|
||||
q = usertypes.Question()
|
||||
q.title = title
|
||||
q.text = text
|
||||
q.mode = mode
|
||||
self.shutting_down.connect(q.abort)
|
||||
abort_on = [self.shutting_down]
|
||||
if owner is not None:
|
||||
owner.destroyed.connect(q.abort)
|
||||
abort_on.append(owner.destroyed)
|
||||
|
||||
# This might be a generic network manager, e.g. one belonging to a
|
||||
# DownloadManager. In this case, just skip the webview thing.
|
||||
if self._tab_id is not None:
|
||||
tab = objreg.get('tab', scope='tab', window=self._win_id,
|
||||
tab=self._tab_id)
|
||||
tab.load_started.connect(q.abort)
|
||||
bridge = objreg.get('message-bridge', scope='window',
|
||||
window=self._win_id)
|
||||
bridge.ask(q, blocking=True)
|
||||
q.deleteLater()
|
||||
return q.answer
|
||||
abort_on.append(tab.load_started)
|
||||
|
||||
return message.ask(win_id=self._win_id, title=title, text=text, mode=mode,
|
||||
abort_on=abort_on)
|
||||
|
||||
def shutdown(self):
|
||||
"""Abort all running requests."""
|
||||
|
@ -98,8 +98,10 @@ class BrowserPage(QWebPage):
|
||||
if (self._is_shutting_down or
|
||||
config.get('content', 'ignore-javascript-prompt')):
|
||||
return (False, "")
|
||||
answer = self._ask('Javascript prompt', msg,
|
||||
usertypes.PromptMode.text, default)
|
||||
answer = message.ask(self._win_id, 'Javascript prompt', msg,
|
||||
usertypes.PromptMode.text, default=default,
|
||||
abort_on=[self.loadStarted,
|
||||
self.shutting_down])
|
||||
if answer is None:
|
||||
return (False, "")
|
||||
else:
|
||||
@ -196,31 +198,6 @@ class BrowserPage(QWebPage):
|
||||
suggested_file)
|
||||
return True
|
||||
|
||||
def _ask(self, title, text, mode, default=None):
|
||||
"""Ask a blocking question in the statusbar.
|
||||
|
||||
Args:
|
||||
title: The title to display.
|
||||
text: The text to display to the user.
|
||||
mode: A PromptMode.
|
||||
default: The default value to display.
|
||||
|
||||
Return:
|
||||
The answer the user gave or None if the prompt was cancelled.
|
||||
"""
|
||||
q = usertypes.Question()
|
||||
q.title = title
|
||||
q.text = text
|
||||
q.mode = mode
|
||||
q.default = default
|
||||
self.loadStarted.connect(q.abort)
|
||||
self.shutting_down.connect(q.abort)
|
||||
bridge = objreg.get('message-bridge', scope='window',
|
||||
window=self._win_id)
|
||||
bridge.ask(q, blocking=True)
|
||||
q.deleteLater()
|
||||
return q.answer
|
||||
|
||||
def _show_pdfjs(self, reply):
|
||||
"""Show the reply with pdfjs."""
|
||||
try:
|
||||
@ -335,11 +312,6 @@ class BrowserPage(QWebPage):
|
||||
}
|
||||
config_val = config.get(*options[feature])
|
||||
if config_val == 'ask':
|
||||
bridge = objreg.get('message-bridge', scope='window',
|
||||
window=self._win_id)
|
||||
q = usertypes.Question(bridge)
|
||||
q.mode = usertypes.PromptMode.yesno
|
||||
|
||||
msgs = {
|
||||
QWebPage.Notifications: 'show notifications',
|
||||
QWebPage.Geolocation: 'access your location',
|
||||
@ -347,30 +319,28 @@ class BrowserPage(QWebPage):
|
||||
|
||||
host = frame.url().host()
|
||||
if host:
|
||||
q.text = "Allow the website at {} to {}?".format(
|
||||
text = "Allow the website at {} to {}?".format(
|
||||
frame.url().host(), msgs[feature])
|
||||
else:
|
||||
q.text = "Allow the website to {}?".format(msgs[feature])
|
||||
text = "Allow the website to {}?".format(msgs[feature])
|
||||
|
||||
yes_action = functools.partial(
|
||||
self.setFeaturePermission, frame, feature,
|
||||
QWebPage.PermissionGrantedByUser)
|
||||
q.answered_yes.connect(yes_action)
|
||||
|
||||
no_action = functools.partial(
|
||||
self.setFeaturePermission, frame, feature,
|
||||
QWebPage.PermissionDeniedByUser)
|
||||
q.answered_no.connect(no_action)
|
||||
q.cancelled.connect(no_action)
|
||||
|
||||
self.shutting_down.connect(q.abort)
|
||||
q.completed.connect(q.deleteLater)
|
||||
|
||||
question = message.confirm_async(self._win_id,
|
||||
yes_action=yes_action,
|
||||
no_action=no_action,
|
||||
cancel_action=cancel_action,
|
||||
abort_on=[self.shutting_down,
|
||||
self.loadStarted],
|
||||
title='Permission request',
|
||||
text=text)
|
||||
self.featurePermissionRequestCanceled.connect(functools.partial(
|
||||
self.on_feature_permission_cancelled, q, frame, feature))
|
||||
self.loadStarted.connect(q.abort)
|
||||
|
||||
bridge.ask(q, blocking=False)
|
||||
self.on_feature_permission_cancelled, question, frame, feature))
|
||||
elif config_val:
|
||||
self.setFeaturePermission(frame, feature,
|
||||
QWebPage.PermissionGrantedByUser)
|
||||
@ -480,7 +450,9 @@ class BrowserPage(QWebPage):
|
||||
if (self._is_shutting_down or
|
||||
config.get('content', 'ignore-javascript-alert')):
|
||||
return
|
||||
self._ask('Javascript alert', msg, usertypes.PromptMode.alert)
|
||||
message.ask(self._win_id, 'Javascript alert', msg,
|
||||
usertypes.PromptMode.alert,
|
||||
abort_on=[self.loadStarted, self.shutting_down])
|
||||
|
||||
def javaScriptConfirm(self, frame, msg):
|
||||
"""Override javaScriptConfirm to use the statusbar."""
|
||||
@ -490,7 +462,9 @@ class BrowserPage(QWebPage):
|
||||
|
||||
if self._is_shutting_down:
|
||||
return False
|
||||
ans = self._ask('Javascript confirm', msg, usertypes.PromptMode.yesno)
|
||||
ans = message.ask(self._win_id, 'Javascript confirm', msg,
|
||||
usertypes.PromptMode.yesno,
|
||||
abort_on=[self.loadStarted, self.shutting_down])
|
||||
return bool(ans)
|
||||
|
||||
def javaScriptConsoleMessage(self, msg, line, source):
|
||||
|
@ -343,17 +343,11 @@ class _BasePrompt(QWidget):
|
||||
return utils.get_repr(self, question=self.question, constructor=True)
|
||||
|
||||
def _init_title(self, question):
|
||||
if question.title is None:
|
||||
title = question.text
|
||||
text = None
|
||||
else:
|
||||
title = question.title
|
||||
text = question.text
|
||||
|
||||
title_label = QLabel('<b>{}</b>'.format(title), self)
|
||||
assert question.title is not None, question
|
||||
title_label = QLabel('<b>{}</b>'.format(question.title), self)
|
||||
self._vbox.addWidget(title_label)
|
||||
if text is not None:
|
||||
text_label = QLabel(text)
|
||||
if question.text is not None:
|
||||
text_label = QLabel(question.text)
|
||||
self._vbox.addWidget(text_label)
|
||||
|
||||
def accept(self, value=None):
|
||||
|
@ -76,7 +76,21 @@ def info(message):
|
||||
global_bridge.show_message.emit(usertypes.MessageLevel.info, message)
|
||||
|
||||
|
||||
def ask(win_id, message, mode, default=None):
|
||||
def _build_question(title, mode, *, default=None, text=None, abort_on=()):
|
||||
"""Common function for ask/ask_async."""
|
||||
if not isinstance(mode, usertypes.PromptMode):
|
||||
raise TypeError("Mode {} is no PromptMode member!".format(mode))
|
||||
question = usertypes.Question()
|
||||
question.title = title
|
||||
question.text = text
|
||||
question.mode = mode
|
||||
question.default = default
|
||||
for sig in abort_on:
|
||||
sig.connect(question.abort)
|
||||
return question
|
||||
|
||||
|
||||
def ask(win_id, *args, **kwargs):
|
||||
"""Ask a modular question in the statusbar (blocking).
|
||||
|
||||
Args:
|
||||
@ -84,21 +98,21 @@ def ask(win_id, message, mode, default=None):
|
||||
message: The message to display to the user.
|
||||
mode: A PromptMode.
|
||||
default: The default value to display.
|
||||
text: Additional text to show
|
||||
abort_on: A list of signals which abort the question if emitted.
|
||||
|
||||
Return:
|
||||
The answer the user gave or None if the prompt was cancelled.
|
||||
"""
|
||||
q = usertypes.Question()
|
||||
q.text = message
|
||||
q.mode = mode
|
||||
q.default = default
|
||||
question = _build_question(*args, **kwargs)
|
||||
bridge = objreg.get('message-bridge', scope='window', window=win_id)
|
||||
bridge.ask(q, blocking=True)
|
||||
q.deleteLater()
|
||||
return q.answer
|
||||
bridge.ask(question, blocking=True)
|
||||
answer = question.answer
|
||||
question.deleteLater()
|
||||
return answer
|
||||
|
||||
|
||||
def ask_async(win_id, message, mode, handler, default=None):
|
||||
def ask_async(win_id, text, mode, handler, **kwargs):
|
||||
"""Ask an async question in the statusbar.
|
||||
|
||||
Args:
|
||||
@ -107,20 +121,17 @@ def ask_async(win_id, message, mode, handler, default=None):
|
||||
mode: A PromptMode.
|
||||
handler: The function to get called with the answer as argument.
|
||||
default: The default value to display.
|
||||
text: Additional text to show.
|
||||
"""
|
||||
if not isinstance(mode, usertypes.PromptMode):
|
||||
raise TypeError("Mode {} is no PromptMode member!".format(mode))
|
||||
q = usertypes.Question()
|
||||
q.text = message
|
||||
q.mode = mode
|
||||
q.default = default
|
||||
q.answered.connect(handler)
|
||||
q.completed.connect(q.deleteLater)
|
||||
question = _build_question(text, mode, **kwargs)
|
||||
question.answered.connect(handler)
|
||||
question.completed.connect(question.deleteLater)
|
||||
bridge = objreg.get('message-bridge', scope='window', window=win_id)
|
||||
bridge.ask(q, blocking=False)
|
||||
bridge.ask(question, blocking=False)
|
||||
|
||||
|
||||
def confirm_async(win_id, message, yes_action, no_action=None, default=None):
|
||||
def confirm_async(win_id, yes_action, no_action=None, cancel_action=None,
|
||||
*args, **kwargs):
|
||||
"""Ask a yes/no question to the user and execute the given actions.
|
||||
|
||||
Args:
|
||||
@ -128,18 +139,25 @@ def confirm_async(win_id, message, yes_action, no_action=None, default=None):
|
||||
message: The message to display to the user.
|
||||
yes_action: Callable to be called when the user answered yes.
|
||||
no_action: Callable to be called when the user answered no.
|
||||
cancel_action: Callable to be called when the user cancelled the
|
||||
question.
|
||||
default: True/False to set a default value, or None.
|
||||
text: Additional text to show.
|
||||
|
||||
Return:
|
||||
The question object.
|
||||
"""
|
||||
q = usertypes.Question()
|
||||
q.text = message
|
||||
q.mode = usertypes.PromptMode.yesno
|
||||
q.default = default
|
||||
q.answered_yes.connect(yes_action)
|
||||
question = self._build_question(*args, **kwargs)
|
||||
question.answered_yes.connect(yes_action)
|
||||
if no_action is not None:
|
||||
q.answered_no.connect(no_action)
|
||||
q.completed.connect(q.deleteLater)
|
||||
question.answered_no.connect(no_action)
|
||||
if cancel_action is not None:
|
||||
question.cancelled.connect(cancel_action)
|
||||
|
||||
question.completed.connect(q.deleteLater)
|
||||
bridge = objreg.get('message-bridge', scope='window', window=win_id)
|
||||
bridge.ask(q, blocking=False)
|
||||
bridge.ask(question, blocking=False)
|
||||
return question
|
||||
|
||||
|
||||
class GlobalMessageBridge(QObject):
|
||||
|
Loading…
Reference in New Issue
Block a user