Make yes/no questions work
This commit is contained in:
parent
f43549d452
commit
cfd70e7821
@ -55,7 +55,8 @@ from qutebrowser.config.config import ConfigManager
|
||||
from qutebrowser.keyinput.modeman import ModeManager
|
||||
from qutebrowser.widgets.mainwindow import MainWindow
|
||||
from qutebrowser.widgets.crash import ExceptionCrashDialog, FatalCrashDialog
|
||||
from qutebrowser.keyinput.modeparsers import NormalKeyParser, HintKeyParser
|
||||
from qutebrowser.keyinput.modeparsers import (NormalKeyParser, HintKeyParser,
|
||||
PromptKeyParser)
|
||||
from qutebrowser.keyinput.keyparser import PassthroughKeyParser
|
||||
from qutebrowser.commands.managers import CommandManager, SearchManager
|
||||
from qutebrowser.commands.exceptions import CommandError
|
||||
@ -212,6 +213,7 @@ class QuteBrowser(QApplication):
|
||||
'passthrough': PassthroughKeyParser('keybind.passthrough', self),
|
||||
'command': PassthroughKeyParser('keybind.command', self),
|
||||
'prompt': PassthroughKeyParser('keybind.prompt', self),
|
||||
'yesno': PromptKeyParser(self),
|
||||
}
|
||||
self.modeman = ModeManager()
|
||||
self.modeman.register('normal', self._keyparsers['normal'].handle)
|
||||
@ -225,6 +227,7 @@ class QuteBrowser(QApplication):
|
||||
passthrough=True)
|
||||
self.modeman.register('prompt', self._keyparsers['prompt'].handle,
|
||||
passthrough=True)
|
||||
self.modeman.register('yesno', self._keyparsers['yesno'].handle)
|
||||
|
||||
def _init_log(self):
|
||||
"""Initialisation of the logging output.
|
||||
|
@ -121,8 +121,13 @@ SECTION_DESC = {
|
||||
" leave-mode: Leave the command mode."),
|
||||
'keybind.prompt': (
|
||||
"Keybindings for prompts in the status line.\n"
|
||||
"You can bind normal keys in this mode, but they will be only active "
|
||||
"when a yes/no-prompt is asked. For other prompt modes, you can only "
|
||||
"bind special keys.\n"
|
||||
"Useful hidden commands to map in this section:\n"
|
||||
" prompt-accept: Confirm the entered value\n"
|
||||
" prompt-accept: Confirm the entered value.\n"
|
||||
" prompt-yes: Answer yes to a yes/no question.\n"
|
||||
" prompt-no: Answer no to a yes/no question.\n"
|
||||
" leave-mode: Leave the prompt mode."),
|
||||
'aliases': (
|
||||
"Aliases for commands.\n"
|
||||
@ -701,6 +706,8 @@ DATA = OrderedDict([
|
||||
('<Escape>', 'leave-mode'),
|
||||
('<Ctrl-N>', 'leave-mode'),
|
||||
('<Return>', 'prompt-accept'),
|
||||
('y', 'prompt-yes'),
|
||||
('n', 'prompt-no'),
|
||||
)),
|
||||
|
||||
('aliases', sect.ValueList(
|
||||
|
@ -59,6 +59,17 @@ class NormalKeyParser(CommandKeyParser):
|
||||
return super()._handle_single_key(e)
|
||||
|
||||
|
||||
class PromptKeyParser(CommandKeyParser):
|
||||
|
||||
"""KeyParser for yes/no prompts."""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent, supports_count=False, supports_chains=True)
|
||||
# We don't want an extra section for this in the config, so we just
|
||||
# abuse the keybind.prompt section.
|
||||
self.read_config('keybind.prompt')
|
||||
|
||||
|
||||
class HintKeyParser(CommandKeyParser):
|
||||
|
||||
"""KeyChainParser for hints.
|
||||
|
@ -22,6 +22,7 @@ from PyQt5.QtWidgets import QHBoxLayout, QWidget, QLineEdit
|
||||
|
||||
import qutebrowser.keyinput.modeman as modeman
|
||||
import qutebrowser.commands.utils as cmdutils
|
||||
import qutebrowser.config.config as config
|
||||
from qutebrowser.widgets.statusbar._textbase import TextBase
|
||||
from qutebrowser.widgets.misc import MinimalLineEdit
|
||||
from qutebrowser.utils.usertypes import PromptMode, Question
|
||||
@ -36,7 +37,7 @@ class Prompt(QWidget):
|
||||
loop: A local QEventLoop to spin in exec_.
|
||||
_hbox: The QHBoxLayout used to display the text and prompt.
|
||||
_txt: The TextBase instance (QLabel) used to display the prompt text.
|
||||
_input: The QueryInput instance (QLineEdit) used for the input.
|
||||
_input: The MinimalLineEdit instance (QLineEdit) used for the input.
|
||||
|
||||
Signals:
|
||||
show_prompt: Emitted when the prompt widget wants to be shown.
|
||||
@ -61,7 +62,7 @@ class Prompt(QWidget):
|
||||
self._txt = TextBase()
|
||||
self._hbox.addWidget(self._txt)
|
||||
|
||||
self._input = _QueryInput()
|
||||
self._input = MinimalLineEdit()
|
||||
self._hbox.addWidget(self._input)
|
||||
|
||||
def on_mode_left(self, mode):
|
||||
@ -71,7 +72,7 @@ class Prompt(QWidget):
|
||||
cancelled: Emitted when the mode was forcibly left by the user
|
||||
without answering the question.
|
||||
"""
|
||||
if mode == 'prompt':
|
||||
if mode in ['prompt', 'yesno']:
|
||||
self._txt.setText('')
|
||||
self._input.clear()
|
||||
self._input.setEchoMode(QLineEdit.Normal)
|
||||
@ -100,10 +101,36 @@ class Prompt(QWidget):
|
||||
self.question.answer = (self.question.user, password)
|
||||
modeman.leave('prompt', 'prompt accept')
|
||||
self.hide_prompt.emit()
|
||||
else:
|
||||
# User just entered all information needed in some other mode.
|
||||
elif self.question.mode == PromptMode.text:
|
||||
# User just entered text.
|
||||
self.question.answer = self._input.text()
|
||||
modeman.leave('prompt', 'prompt accept')
|
||||
elif self.question.mode == PromptMode.yesno:
|
||||
# User wants to accept the default of a yes/no question.
|
||||
self.question.answer = self.question.default
|
||||
modeman.leave('yesno', 'yesno accept')
|
||||
else:
|
||||
raise ValueError("Invalid question mode!")
|
||||
|
||||
@cmdutils.register(instance='mainwindow.status.prompt', hide=True,
|
||||
modes=['yesno'])
|
||||
def prompt_yes(self):
|
||||
"""Answer yes to a yes/no prompt."""
|
||||
if self.question.mode != PromptMode.yesno:
|
||||
# We just ignore this if we don't have a yes/no question.
|
||||
return
|
||||
self.question.answer = True
|
||||
modeman.leave('yesno', 'yesno accept')
|
||||
|
||||
@cmdutils.register(instance='mainwindow.status.prompt', hide=True,
|
||||
modes=['yesno'])
|
||||
def prompt_no(self):
|
||||
"""Answer no to a yes/no prompt."""
|
||||
if self.question.mode != PromptMode.yesno:
|
||||
# We just ignore this if we don't have a yes/no question.
|
||||
return
|
||||
self.question.answer = False
|
||||
modeman.leave('yesno', 'prompt accept')
|
||||
|
||||
def display(self):
|
||||
"""Display the question in self.question in the widget.
|
||||
@ -114,27 +141,31 @@ class Prompt(QWidget):
|
||||
q = self.question
|
||||
if q.mode == PromptMode.yesno:
|
||||
if q.default is None:
|
||||
suffix = " [y/n]"
|
||||
suffix = ""
|
||||
elif q.default:
|
||||
suffix = " [Y/n]"
|
||||
suffix = " (yes)"
|
||||
else:
|
||||
suffix = " [y/N]"
|
||||
suffix = " (no)"
|
||||
self._txt.setText(q.text + suffix)
|
||||
self._input.hide()
|
||||
mode = 'yesno'
|
||||
elif q.mode == PromptMode.text:
|
||||
self._txt.setText(q.text)
|
||||
if q.default:
|
||||
self._input.setText(q.default)
|
||||
self._input.show()
|
||||
mode = 'prompt'
|
||||
elif q.mode == PromptMode.user_pwd:
|
||||
self._txt.setText(q.text)
|
||||
if q.default:
|
||||
self._input.setText(q.default)
|
||||
self._input.show()
|
||||
mode = 'prompt'
|
||||
else:
|
||||
raise ValueError("Invalid prompt mode!")
|
||||
self._input.setFocus()
|
||||
self.show_prompt.emit()
|
||||
modeman.enter(mode, 'question asked')
|
||||
|
||||
@pyqtSlot(Question, bool)
|
||||
def ask_question(self, question, blocking):
|
||||
@ -163,13 +194,3 @@ class Prompt(QWidget):
|
||||
self.cancelled.connect(self.loop.quit)
|
||||
self.loop.exec_()
|
||||
return self.question.answer
|
||||
|
||||
|
||||
class _QueryInput(MinimalLineEdit):
|
||||
|
||||
"""QLineEdit used for input."""
|
||||
|
||||
def focusInEvent(self, e):
|
||||
"""Extend focusInEvent to enter command mode."""
|
||||
modeman.enter('prompt', 'auth focus')
|
||||
super().focusInEvent(e)
|
||||
|
Loading…
Reference in New Issue
Block a user