Clean up prompt code
This commit is contained in:
parent
20f8c2b8b4
commit
f43549d452
@ -40,8 +40,7 @@ from argparse import ArgumentParser
|
||||
from base64 import b64encode
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
|
||||
from PyQt5.QtCore import pyqtSlot, QTimer, QEventLoop
|
||||
from PyQt5.QtCore import QStandardPaths
|
||||
from PyQt5.QtCore import pyqtSlot, QTimer, QEventLoop, Qt, QStandardPaths
|
||||
|
||||
import qutebrowser
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
@ -366,10 +365,6 @@ class QuteBrowser(QApplication):
|
||||
self.lastWindowClosed.connect(self.shutdown)
|
||||
tabs.quit.connect(self.shutdown)
|
||||
tabs.currentChanged.connect(self.mainwindow.update_inspector)
|
||||
self.networkmanager.authenticationRequired.connect(
|
||||
status.on_authentication_required)
|
||||
self.networkmanager.proxyAuthenticationRequired.connect(
|
||||
status.on_proxy_authentication_required)
|
||||
|
||||
# status bar
|
||||
self.modeman.entered.connect(status.on_mode_entered)
|
||||
@ -396,6 +391,8 @@ class QuteBrowser(QApplication):
|
||||
self.messagebridge.info.connect(status.disp_temp_text)
|
||||
self.messagebridge.text.connect(status.set_text)
|
||||
self.messagebridge.set_cmd_text.connect(cmd.set_cmd_text)
|
||||
self.messagebridge.question.connect(status.prompt.ask_question,
|
||||
Qt.DirectConnection)
|
||||
|
||||
# config
|
||||
self.config.style_changed.connect(style.invalidate_caches)
|
||||
|
@ -23,6 +23,7 @@ from PyQt5.QtNetwork import QNetworkAccessManager
|
||||
import qutebrowser.config.config as config
|
||||
import qutebrowser.utils.message as message
|
||||
from qutebrowser.network.qutescheme import QuteSchemeHandler
|
||||
from qutebrowser.utils.usertypes import PromptMode
|
||||
|
||||
|
||||
class NetworkManager(QNetworkAccessManager):
|
||||
@ -44,6 +45,9 @@ class NetworkManager(QNetworkAccessManager):
|
||||
if cookiejar is not None:
|
||||
self.setCookieJar(cookiejar)
|
||||
self.sslErrors.connect(self.on_ssl_errors)
|
||||
self.authenticationRequired.connect(self.on_authentication_required)
|
||||
self.proxyAuthenticationRequired.connect(
|
||||
self.on_proxy_authentication_required)
|
||||
|
||||
def abort_requests(self):
|
||||
"""Abort all running requests."""
|
||||
@ -68,6 +72,27 @@ class NetworkManager(QNetworkAccessManager):
|
||||
queue=True)
|
||||
reply.ignoreSslErrors()
|
||||
|
||||
@pyqtSlot('QNetworkReply', 'QAuthenticator')
|
||||
def on_authentication_required(self, reply, authenticator):
|
||||
"""Called when a website needs authentication."""
|
||||
answer = message.modular_question(
|
||||
text="Username ({}):".format(authenticator.realm()),
|
||||
mode=PromptMode.user_pwd)
|
||||
if answer is not None:
|
||||
user, password = answer
|
||||
authenticator.setUser(user)
|
||||
authenticator.setPassword(password)
|
||||
|
||||
@pyqtSlot('QNetworkProxy', 'QAuthenticator')
|
||||
def on_proxy_authentication_required(self, proxy, authenticator):
|
||||
answer = message.modular_question(
|
||||
text="Proxy username ({}):".format(authenticator.realm()),
|
||||
mode=PromptMode.user_pwd)
|
||||
if answer is not None:
|
||||
user, password = answer
|
||||
authenticator.setUser(user)
|
||||
authenticator.setPassword(password)
|
||||
|
||||
def createRequest(self, op, req, outgoing_data):
|
||||
"""Return a new QNetworkReply object.
|
||||
|
||||
|
@ -21,6 +21,8 @@ import logging
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, QCoreApplication
|
||||
|
||||
from qutebrowser.utils.usertypes import Question
|
||||
|
||||
|
||||
def instance():
|
||||
"""Get the global messagebridge instance."""
|
||||
@ -60,6 +62,25 @@ def text(message):
|
||||
instance().text.emit(message)
|
||||
|
||||
|
||||
def modular_question(text, mode, default=None):
|
||||
"""Ask a modular question in the statusbar.
|
||||
|
||||
Args:
|
||||
text: The message 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 = Question()
|
||||
q.text = text
|
||||
q.mode = mode
|
||||
q.default = default
|
||||
instance().question.emit(q, True)
|
||||
return q.answer
|
||||
|
||||
|
||||
def clear():
|
||||
"""Clear a persistent message in the statusbar."""
|
||||
instance().text.emit('')
|
||||
@ -78,3 +99,4 @@ class MessageBridge(QObject):
|
||||
info = pyqtSignal(str, bool)
|
||||
text = pyqtSignal(str)
|
||||
set_cmd_text = pyqtSignal(str)
|
||||
question = pyqtSignal(Question, bool)
|
||||
|
@ -25,6 +25,9 @@ import operator
|
||||
import logging
|
||||
import collections.abc
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QObject
|
||||
|
||||
|
||||
_UNSET = object()
|
||||
|
||||
|
||||
@ -241,3 +244,50 @@ class FakeDict:
|
||||
|
||||
def __repr__(self):
|
||||
return "FakeDict('{}')".format(self._val)
|
||||
|
||||
|
||||
# The mode of a Question.
|
||||
PromptMode = enum('yesno', 'text', 'user_pwd')
|
||||
|
||||
|
||||
class Question(QObject):
|
||||
|
||||
"""A question asked to the user, e.g. via the status bar.
|
||||
|
||||
Attributes:
|
||||
mode: A PromptMode enum member.
|
||||
yesno: A question which can be answered with yes/no.
|
||||
text: A question which requires a free text answer.
|
||||
user_pwd: A question for an username and password.
|
||||
default: The default value.
|
||||
For yesno, None (no default), True or False.
|
||||
For text, a default text as string.
|
||||
For user_pwd, a default username as string.
|
||||
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).
|
||||
|
||||
Signals:
|
||||
answered: Emitted when the question has been answered by the user.
|
||||
"""
|
||||
|
||||
answered = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.mode = None
|
||||
self.default = None
|
||||
self.text = None
|
||||
self.user = None
|
||||
self._answer = None
|
||||
|
||||
@property
|
||||
def answer(self):
|
||||
"""Getter for answer so we can define a setter."""
|
||||
return self._answer
|
||||
|
||||
@answer.setter
|
||||
def answer(self, val):
|
||||
"""Setter for answer to emit the answered signal after setting."""
|
||||
self._answer = val
|
||||
self.answered.emit()
|
||||
|
@ -17,59 +17,14 @@
|
||||
|
||||
"""Prompt shown in the statusbar."""
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QEventLoop, QObject
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QEventLoop
|
||||
from PyQt5.QtWidgets import QHBoxLayout, QWidget, QLineEdit
|
||||
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
from qutebrowser.widgets.statusbar._textbase import TextBase
|
||||
from qutebrowser.widgets.misc import MinimalLineEdit
|
||||
from qutebrowser.utils.usertypes import enum
|
||||
|
||||
PromptMode = enum('yesno', 'text', 'user_pwd')
|
||||
|
||||
|
||||
class Question(QObject):
|
||||
|
||||
"""A question asked to the user via the status bar.
|
||||
|
||||
Attributes:
|
||||
mode: A PromptMode enum member.
|
||||
yesno: A question which can be answered with yes/no.
|
||||
text: A question which requires a free text answer.
|
||||
user_pwd: A question for an username and password.
|
||||
default: The default value.
|
||||
For yesno, None (no default), True or False.
|
||||
For text, a default text as string.
|
||||
For user_pwd, a default username as string.
|
||||
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).
|
||||
|
||||
Signals:
|
||||
answered: Emitted when the question has been answered by the user.
|
||||
"""
|
||||
|
||||
answered = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.mode = None
|
||||
self.default = None
|
||||
self.text = None
|
||||
self.user = None
|
||||
self._answer = None
|
||||
|
||||
@property
|
||||
def answer(self):
|
||||
"""Getter for answer so we can define a setter."""
|
||||
return self._answer
|
||||
|
||||
@answer.setter
|
||||
def answer(self, val):
|
||||
"""Setter for answer to emit the answered signal after setting."""
|
||||
self._answer = val
|
||||
self.answered.emit()
|
||||
from qutebrowser.utils.usertypes import PromptMode, Question
|
||||
|
||||
|
||||
class Prompt(QWidget):
|
||||
@ -181,13 +136,29 @@ class Prompt(QWidget):
|
||||
self._input.setFocus()
|
||||
self.show_prompt.emit()
|
||||
|
||||
@pyqtSlot(Question, bool)
|
||||
def ask_question(self, question, blocking):
|
||||
"""Slot which is called when there's a question to ask to the user.
|
||||
|
||||
Return:
|
||||
The answer of the user when blocking=True.
|
||||
None if blocking=False.
|
||||
|
||||
Args:
|
||||
question: The Question object to ask.
|
||||
blocking: If True, exec_ is called and the result is returned.
|
||||
"""
|
||||
self.question = question
|
||||
self.display()
|
||||
if blocking:
|
||||
return self.exec_()
|
||||
|
||||
def exec_(self):
|
||||
"""Local eventloop to spin in for a blocking question.
|
||||
|
||||
Return:
|
||||
The answer to the question. No, it's not always 42.
|
||||
"""
|
||||
self.display()
|
||||
self.question.answered.connect(self.loop.quit)
|
||||
self.cancelled.connect(self.loop.quit)
|
||||
self.loop.exec_()
|
||||
|
@ -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, Question
|
||||
from qutebrowser.widgets.statusbar._prompt import Prompt
|
||||
from qutebrowser.config.style import set_register_stylesheet, get_stylesheet
|
||||
|
||||
|
||||
@ -317,18 +317,6 @@ class StatusBar(QWidget):
|
||||
self._text_pop_timer.setInterval(config.get('ui',
|
||||
'message-timeout'))
|
||||
|
||||
@pyqtSlot('QNetworkReply', 'QAuthenticator')
|
||||
def on_authentication_required(self, reply, authenticator):
|
||||
q = Question()
|
||||
q.mode = PromptMode.user_pwd
|
||||
q.text = "Username ({}):".format(authenticator.realm())
|
||||
self.prompt.question = q
|
||||
answer = self.prompt.exec_()
|
||||
if answer is not None:
|
||||
user, password = answer
|
||||
authenticator.setUser(user)
|
||||
authenticator.setPassword(password)
|
||||
|
||||
@pyqtSlot('QNetworkProxy', 'QAuthenticator')
|
||||
def on_proxy_authentication_required(self, proxy, authenticator):
|
||||
q = Question()
|
||||
|
Loading…
Reference in New Issue
Block a user