From fce591839b91510d261d40fe6b77d57e868b7c3d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 13 Jun 2014 18:17:27 +0200 Subject: [PATCH] Abort filename prompt when download is cancelled. --- qutebrowser/browser/downloads.py | 26 ++++++++++++++++--------- qutebrowser/utils/usertypes.py | 14 +++++++++++++ qutebrowser/widgets/statusbar/prompt.py | 4 +++- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index c67cd6341..10e81c2f3 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -26,7 +26,7 @@ from PyQt5.QtNetwork import QNetworkReply import qutebrowser.config.config as config import qutebrowser.utils.message as message from qutebrowser.utils.log import downloads as logger -from qutebrowser.utils.usertypes import PromptMode +from qutebrowser.utils.usertypes import PromptMode, Question from qutebrowser.utils.misc import (interpolate_color, format_seconds, format_size) @@ -46,7 +46,7 @@ class DownloadItem(QObject): speed: The current download speed, in bytes per second. fileobj: The file object to download the file to. filename: The filename of the download. - cancelled: Whether the download was cancelled. + is_cancelled: Whether the download was cancelled. _last_done: The count of bytes which where downloaded when calculating the speed the last time. _last_percentage: The remembered percentage for data_changed. @@ -54,6 +54,7 @@ class DownloadItem(QObject): Signals: data_changed: The downloads metadata changed. finished: The download was finished. + cancelled: The download was cancelled. error: An error with the download occured. arg: The error message as string. """ @@ -62,6 +63,7 @@ class DownloadItem(QObject): data_changed = pyqtSignal() finished = pyqtSignal() error = pyqtSignal(str) + cancelled = pyqtSignal() def __init__(self, reply, parent=None): """Constructor. @@ -77,7 +79,7 @@ class DownloadItem(QObject): self.basename = '???' self.fileobj = None self.filename = None - self.cancelled = False + self.is_cancelled = False self._do_delayed_write = False self._last_done = None self._last_percentage = None @@ -152,7 +154,8 @@ class DownloadItem(QObject): def cancel(self): """Cancel the download.""" logger.debug("cancelled") - self.cancelled = True + self.cancelled.emit() + self.is_cancelled = True self.reply.abort() self.reply.deleteLater() if self.fileobj is not None: @@ -221,7 +224,7 @@ class DownloadItem(QObject): """ self.bytes_done = self.bytes_total self.timer.stop() - if self.cancelled: + if self.is_cancelled: return logger.debug("Reply finished, fileobj {}".format(self.fileobj)) if self.fileobj is None: @@ -340,10 +343,15 @@ class DownloadManager(QObject): self.download_about_to_be_added.emit(len(self.downloads) + 1) self.downloads.append(download) self.download_added.emit() - message.question("Save file to:", mode=PromptMode.text, - handler=download.set_filename, - cancelled_handler=download.cancel, - default=suggested_filepath) + + q = Question() + q.text = "Save file to:" + q.mode = PromptMode.text + q.default = suggested_filepath + q.answered.connect(download.set_filename) + q.cancelled.connect(download.cancel) + download.cancelled.connect(q.abort) + message.instance().question.emit(q, False) @pyqtSlot() def on_finished(self): diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 5be8a4b6b..dba32e03e 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -250,6 +250,7 @@ class Question(QObject): text: The prompt text to display to the user. user: The value the user entered as username. answer: The value the user entered (as password for user_pwd). + is_aborted: Whether the question was aborted. Signals: answered: Emitted when the question has been answered by the user. @@ -257,6 +258,8 @@ class Question(QObject): it can be emitted after the mode is left. arg: The answer to the question. cancelled: Emitted when the question has been cancelled by the user. + aborted: Emitted when the question was aborted programatically. + In this case, cancelled is not emitted. answered_yes: Convienience signal emitted when a yesno question was answered with yes. answered_no: Convienience signal emitted when a yesno question was @@ -265,6 +268,7 @@ class Question(QObject): answered = pyqtSignal(str) cancelled = pyqtSignal() + aborted = pyqtSignal() answered_yes = pyqtSignal() answered_no = pyqtSignal() @@ -275,3 +279,13 @@ class Question(QObject): self.text = None self.user = None self.answer = None + self.is_aborted = False + + def abort(self): + """Abort the question. + + Emit: + aborted: Always emitted. + """ + self.is_aborted = True + self.aborted.emit() diff --git a/qutebrowser/widgets/statusbar/prompt.py b/qutebrowser/widgets/statusbar/prompt.py index db734cb81..acc1cf52d 100644 --- a/qutebrowser/widgets/statusbar/prompt.py +++ b/qutebrowser/widgets/statusbar/prompt.py @@ -69,7 +69,7 @@ class Prompt(QWidget): self._input.clear() self._input.setEchoMode(QLineEdit.Normal) self.hide_prompt.emit() - if self.question.answer is None: + if self.question.answer is None and not self.question.is_aborted: self.question.cancelled.emit() @cmdutils.register(instance='mainwindow.status.prompt', hide=True, @@ -173,6 +173,7 @@ class Prompt(QWidget): raise ValueError("Invalid prompt mode!") self._input.setFocus() self.show_prompt.emit() + q.aborted.connect(lambda: modeman.maybe_leave(mode, 'aborted')) modeman.enter(mode, 'question asked') @pyqtSlot(Question, bool) @@ -200,5 +201,6 @@ class Prompt(QWidget): """ self.question.answered.connect(self.loop.quit) self.question.cancelled.connect(self.loop.quit) + self.question.aborted.connect(self.loop.quit) self.loop.exec_() return self.question.answer