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