Abort blocking questions when new page is loaded.

Fixes #430.
Fixes #431.
Hopefully fixes #354.
Hopefully fixes #434.
This commit is contained in:
Florian Bruhin 2015-01-03 22:21:47 +01:00
parent f811f511fa
commit 2203db298d
4 changed files with 41 additions and 13 deletions

View File

@ -562,7 +562,8 @@ class DownloadManager(QAbstractListModel):
self._win_id = win_id self._win_id = win_id
self.downloads = [] self.downloads = []
self.questions = [] self.questions = []
self._networkmanager = networkmanager.NetworkManager(win_id, self) self._networkmanager = networkmanager.NetworkManager(
win_id, None, self)
def __repr__(self): def __repr__(self):
return utils.get_repr(self, downloads=len(self.downloads)) return utils.get_repr(self, downloads=len(self.downloads))

View File

@ -47,6 +47,7 @@ class NetworkManager(QNetworkAccessManager):
_scheme_handlers: A dictionary (scheme -> handler) of supported custom _scheme_handlers: A dictionary (scheme -> handler) of supported custom
schemes. schemes.
_win_id: The window ID this NetworkManager is associated with. _win_id: The window ID this NetworkManager is associated with.
_tab_id: The tab ID this NetworkManager is associated with.
Signals: Signals:
shutting_down: Emitted when the QNAM is shutting down. shutting_down: Emitted when the QNAM is shutting down.
@ -54,7 +55,7 @@ class NetworkManager(QNetworkAccessManager):
shutting_down = pyqtSignal() shutting_down = pyqtSignal()
def __init__(self, win_id, parent=None): def __init__(self, win_id, tab_id, parent=None):
log.init.debug("Initializing NetworkManager") log.init.debug("Initializing NetworkManager")
with log.disable_qt_msghandler(): with log.disable_qt_msghandler():
# WORKAROUND for a hang when a message is printed - See: # WORKAROUND for a hang when a message is printed - See:
@ -62,6 +63,7 @@ class NetworkManager(QNetworkAccessManager):
super().__init__(parent) super().__init__(parent)
log.init.debug("NetworkManager init done") log.init.debug("NetworkManager init done")
self._win_id = win_id self._win_id = win_id
self._tab_id = tab_id
self._requests = [] self._requests = []
self._scheme_handlers = { self._scheme_handlers = {
'qute': qutescheme.QuteSchemeHandler(win_id), 'qute': qutescheme.QuteSchemeHandler(win_id),
@ -123,6 +125,9 @@ class NetworkManager(QNetworkAccessManager):
self.shutting_down.connect(q.abort) self.shutting_down.connect(q.abort)
if owner is not None: if owner is not None:
owner.destroyed.connect(q.abort) owner.destroyed.connect(q.abort)
webview = objreg.get('webview', scope='tab', window=self._win_id,
tab=self._tab_id)
webview.loadStarted.connect(q.abort)
bridge = objreg.get('message-bridge', scope='window', bridge = objreg.get('message-bridge', scope='window',
window=self._win_id) window=self._win_id)
bridge.ask(q, blocking=True) bridge.ask(q, blocking=True)

View File

@ -47,7 +47,7 @@ class BrowserPage(QWebPage):
_ignore_load_started: Whether to ignore the next loadStarted signal. _ignore_load_started: Whether to ignore the next loadStarted signal.
""" """
def __init__(self, win_id, parent=None): def __init__(self, win_id, tab_id, parent=None):
super().__init__(parent) super().__init__(parent)
self._win_id = win_id self._win_id = win_id
self._extension_handlers = { self._extension_handlers = {
@ -56,7 +56,8 @@ class BrowserPage(QWebPage):
} }
self._ignore_load_started = False self._ignore_load_started = False
self.error_occured = False self.error_occured = False
self._networkmanager = networkmanager.NetworkManager(win_id, self) self._networkmanager = networkmanager.NetworkManager(
win_id, tab_id, self)
self.setNetworkAccessManager(self._networkmanager) self.setNetworkAccessManager(self._networkmanager)
self.setForwardUnsupportedContent(True) self.setForwardUnsupportedContent(True)
self.printRequested.connect(self.on_print_requested) self.printRequested.connect(self.on_print_requested)
@ -72,8 +73,8 @@ class BrowserPage(QWebPage):
def javaScriptPrompt(self, _frame, msg, default): def javaScriptPrompt(self, _frame, msg, default):
"""Override javaScriptPrompt to use the statusbar.""" """Override javaScriptPrompt to use the statusbar."""
answer = message.ask(self._win_id, "js: {}".format(msg), answer = self._ask("js: {}".format(msg), usertypes.PromptMode.text,
usertypes.PromptMode.text, default) default)
if answer is None: if answer is None:
return (False, "") return (False, "")
else: else:
@ -157,6 +158,28 @@ class BrowserPage(QWebPage):
suggested_file) suggested_file)
return True return True
def _ask(self, text, mode, default=None):
"""Ask a blocking question in the statusbar.
Args:
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.text = text
q.mode = mode
q.default = default
self.loadStarted.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 display_content(self, reply, mimetype): def display_content(self, reply, mimetype):
"""Display a QNetworkReply with an explicitely set mimetype.""" """Display a QNetworkReply with an explicitely set mimetype."""
self.mainFrame().setContent(reply.readAll(), mimetype, reply.url()) self.mainFrame().setContent(reply.readAll(), mimetype, reply.url())
@ -268,13 +291,12 @@ class BrowserPage(QWebPage):
def javaScriptAlert(self, _frame, msg): def javaScriptAlert(self, _frame, msg):
"""Override javaScriptAlert to use the statusbar.""" """Override javaScriptAlert to use the statusbar."""
message.ask(self._win_id, "[js alert] {}".format(msg), self._ask("[js alert] {}".format(msg), usertypes.PromptMode.alert)
usertypes.PromptMode.alert)
def javaScriptConfirm(self, _frame, msg): def javaScriptConfirm(self, _frame, msg):
"""Override javaScriptConfirm to use the statusbar.""" """Override javaScriptConfirm to use the statusbar."""
ans = message.ask(self._win_id, "[js confirm] {}".format(msg), ans = self._ask("[js confirm] {}".format(msg),
usertypes.PromptMode.yesno) usertypes.PromptMode.yesno)
return bool(ans) return bool(ans)
def javaScriptConsoleMessage(self, msg, line, source): def javaScriptConsoleMessage(self, msg, line, source):
@ -293,8 +315,8 @@ class BrowserPage(QWebPage):
def shouldInterruptJavaScript(self): def shouldInterruptJavaScript(self):
"""Override shouldInterruptJavaScript to use the statusbar.""" """Override shouldInterruptJavaScript to use the statusbar."""
answer = message.ask(self._win_id, "Interrupt long-running " answer = self._ask("Interrupt long-running javascript?",
"javascript?", usertypes.PromptMode.yesno) usertypes.PromptMode.yesno)
if answer is None: if answer is None:
answer = True answer = True
return answer return answer

View File

@ -113,7 +113,7 @@ class WebView(QWebView):
window=win_id) window=win_id)
tab_registry[self.tab_id] = self tab_registry[self.tab_id] = self
objreg.register('webview', self, registry=self.registry) objreg.register('webview', self, registry=self.registry)
page = webpage.BrowserPage(win_id, self) page = webpage.BrowserPage(win_id, self.tab_id, self)
self.setPage(page) self.setPage(page)
hintmanager = hints.HintManager(win_id, self.tab_id, self) hintmanager = hints.HintManager(win_id, self.tab_id, self)
hintmanager.mouse_event.connect(self.on_mouse_event) hintmanager.mouse_event.connect(self.on_mouse_event)