diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 8f5b425d4..a0c68287e 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -373,6 +373,7 @@ class QuteBrowser(QApplication): self.modeman.entered.connect(status.on_mode_entered) self.modeman.left.connect(status.on_mode_left) self.modeman.left.connect(status.cmd.on_mode_left) + self.modeman.left.connect(status.prompt.on_mode_left) # commands cmd.got_cmd.connect(self.commandmanager.run_safely) diff --git a/qutebrowser/widgets/statusbar/_prompt.py b/qutebrowser/widgets/statusbar/_prompt.py index 6f68b584f..857723c66 100644 --- a/qutebrowser/widgets/statusbar/_prompt.py +++ b/qutebrowser/widgets/statusbar/_prompt.py @@ -17,7 +17,7 @@ """Prompt shown in the statusbar.""" -from PyQt5.QtCore import pyqtSignal, QEventLoop +from PyQt5.QtCore import pyqtSignal, QEventLoop, QObject from PyQt5.QtWidgets import QLineEdit, QHBoxLayout import qutebrowser.keyinput.modeman as modeman @@ -28,20 +28,37 @@ from qutebrowser.utils.usertypes import enum PromptMode = enum('yesno', 'text', 'user_pwd') +class Question(QObject): + + answered = pyqtSignal() + + def __init__(self, parent=None): + super().__init__(parent) + self.mode = None + self.default = None + self.text = None + self._answer = None + + @property + def answer(self): + return self._answer + + @answer.setter + def answer(self, val): + self._answer = val + self.answered.emit() + + class Prompt(TextBase): - answered = pyqtSignal([str], [bool], [str, str]) accepted = pyqtSignal() + show_prompt = pyqtSignal() hide_prompt = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) - self.mode = None - self.default = None - self.text = None - self.answer = None - + self.question = None self.loop = QEventLoop() self._hbox = QHBoxLayout(self) @@ -65,28 +82,21 @@ class Prompt(TextBase): def _password_entered(self): self.accepted.disconnect(self._password_entered) password = self._input.text() - self.answer = (self._user, password) - self._txt.setText('') - self._input.clear() - self._input.setEchoMode(QLineEdit.Normal) - self.default = None - self.mode = None - self.text = None - self.answered[str, str].emit(*self.answer) + self.question.answer = (self._user, password) modeman.leave('prompt', 'prompt accept') self.hide_prompt.emit() def on_return_pressed(self): self.accepted.disconnect(self.on_return_pressed) - self.answer = self._input.text() - self._txt.setText('') - self.default = None - self.mode = None - self.text = None - # FIXME handle bool correctly - self.answered[str].emit(self.answer) + self.question.answer = self._input.text() modeman.leave('prompt', 'prompt accept') - self.hide_prompt.emit() + + def on_mode_left(self, mode): + if mode == 'prompt': + self._txt.setText('') + self._input.clear() + self._input.setEchoMode(QLineEdit.Normal) + self.hide_prompt.emit() @cmdutils.register(instance='mainwindow.status.prompt', hide=True, modes=['prompt']) @@ -95,36 +105,38 @@ class Prompt(TextBase): self.accepted.emit() def display(self): - if self.mode == PromptMode.yesno: - if self.default is None: + q = self.question + if q.mode == PromptMode.yesno: + if q.default is None: suffix = " [y/n]" - elif self.default: + elif q.default: suffix = " [Y/n]" else: suffix = " [y/N]" - self._txt.setText(self.text + suffix) + self._txt.setText(q.text + suffix) self._input.hide() - elif self.mode == PromptMode.text: - self._txt.setText(self.text) - if self.default: - self._input.setText(self.default) + elif q.mode == PromptMode.text: + self._txt.setText(q.text) + if q.default: + self._input.setText(q.default) self._input.show() self.accepted.connect(self.on_return_pressed) - elif self.mode == PromptMode.user_pwd: - self._txt.setText(self.text) - if self.default: - self._input.setText(self.default) + elif q.mode == PromptMode.user_pwd: + self._txt.setText(q.text) + if q.default: + self._input.setText(q.default) self._input.show() self.accepted.connect(self._user_entered) else: raise ValueError("Invalid prompt mode!") self._input.setFocus() + self.show_prompt.emit() def exec_(self): self.display() - self.answered[str, str].connect(self.loop.quit) + self.question.answered.connect(self.loop.quit) self.loop.exec_() - return self.answer + return self.question.answer class _QueryInput(QLineEdit): diff --git a/qutebrowser/widgets/statusbar/bar.py b/qutebrowser/widgets/statusbar/bar.py index f1c5588ac..2b3afbf7f 100644 --- a/qutebrowser/widgets/statusbar/bar.py +++ b/qutebrowser/widgets/statusbar/bar.py @@ -32,7 +32,7 @@ from qutebrowser.widgets.statusbar._text import Text from qutebrowser.widgets.statusbar._keystring import KeyString from qutebrowser.widgets.statusbar._percentage import Percentage from qutebrowser.widgets.statusbar._url import Url -from qutebrowser.widgets.statusbar._prompt import Prompt, PromptMode +from qutebrowser.widgets.statusbar._prompt import Prompt, PromptMode, Question from qutebrowser.config.style import set_register_stylesheet, get_stylesheet @@ -129,6 +129,7 @@ class StatusBar(QWidget): self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() + self.prompt.show_prompt.connect(self._show_prompt_widget) self.prompt.hide_prompt.connect(self._hide_prompt_widget) self._hide_prompt_widget() @@ -318,14 +319,13 @@ class StatusBar(QWidget): @pyqtSlot('QNetworkReply', 'QAuthenticator') def on_authentication_required(self, reply, authenticator): - self._show_prompt_widget() - self.prompt.mode = PromptMode.user_pwd - self.prompt.text = "Username ({}):".format(authenticator.realm()) + q = Question() + q.mode = PromptMode.user_pwd + q.text = "Username ({}):".format(authenticator.realm()) + self.prompt.question = q user, password = self.prompt.exec_() - self._hide_prompt_widget() authenticator.setUser(user) authenticator.setPassword(password) - logging.debug("user: {} / password: {}".format(user, password)) def resizeEvent(self, e): """Extend resizeEvent of QWidget to emit a resized signal afterwards.