summaryrefslogtreecommitdiff
path: root/qutebrowser/mainwindow/prompt.py
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2019-07-09 12:44:42 +0200
committerFlorian Bruhin <me@the-compiler.org>2019-07-09 12:44:42 +0200
commit25a1189b80426f91a0b9331385f3beaf882161ef (patch)
tree2a13ed661af73408c4da840eb94fc5b3df84f666 /qutebrowser/mainwindow/prompt.py
parent50f530c4494cf87455da308e960301c59d14c89f (diff)
downloadqutebrowser-25a1189b80426f91a0b9331385f3beaf882161ef.tar.gz
qutebrowser-25a1189b80426f91a0b9331385f3beaf882161ef.zip
Add :prompt-accept --save for boolean prompts
Fixes #832
Diffstat (limited to 'qutebrowser/mainwindow/prompt.py')
-rw-r--r--qutebrowser/mainwindow/prompt.py73
1 files changed, 55 insertions, 18 deletions
diff --git a/qutebrowser/mainwindow/prompt.py b/qutebrowser/mainwindow/prompt.py
index 9fd3da8dd..9dfdd2d8a 100644
--- a/qutebrowser/mainwindow/prompt.py
+++ b/qutebrowser/mainwindow/prompt.py
@@ -26,16 +26,17 @@ import functools
import attr
from PyQt5.QtCore import (pyqtSlot, pyqtSignal, Qt, QTimer, QDir, QModelIndex,
- QItemSelectionModel, QObject, QEventLoop)
+ QItemSelectionModel, QObject, QEventLoop, QUrl)
from PyQt5.QtWidgets import (QWidget, QGridLayout, QVBoxLayout, QLineEdit,
QLabel, QFileSystemModel, QTreeView, QSizePolicy,
QSpacerItem)
from qutebrowser.browser import downloads
-from qutebrowser.config import config
+from qutebrowser.config import config, configtypes, configexc
from qutebrowser.utils import usertypes, log, utils, qtutils, objreg, message
from qutebrowser.keyinput import modeman
from qutebrowser.api import cmdutils
+from qutebrowser.utils import urlmatch
prompt_queue = None
@@ -55,7 +56,7 @@ class Error(Exception):
"""Base class for errors in this module."""
-class UnsupportedOperationError(Exception):
+class UnsupportedOperationError(Error):
"""Raised when the prompt class doesn't support the requested operation."""
@@ -377,7 +378,7 @@ class PromptContainer(QWidget):
@cmdutils.register(instance='prompt-container', scope='window',
modes=[usertypes.KeyMode.prompt,
usertypes.KeyMode.yesno])
- def prompt_accept(self, value=None):
+ def prompt_accept(self, value=None, *, save=False):
"""Accept the current prompt.
//
@@ -388,12 +389,15 @@ class PromptContainer(QWidget):
Args:
value: If given, uses this value instead of the entered one.
For boolean prompts, "yes"/"no" are accepted as value.
+ save: Save the value to the config.
"""
question = self._prompt.question
+
try:
- done = self._prompt.accept(value)
+ done = self._prompt.accept(value, save=save)
except Error as e:
raise cmdutils.CommandError(str(e))
+
if done:
message.global_bridge.prompt_done.emit(self._prompt.KEY_MODE)
question.done()
@@ -545,7 +549,12 @@ class _BasePrompt(QWidget):
self._vbox.addLayout(self._key_grid)
- def accept(self, value=None):
+ def _check_save_support(self, save):
+ if save:
+ raise UnsupportedOperationError("Saving answers is only possible "
+ "with yes/no prompts.")
+
+ def accept(self, value=None, save=False):
raise NotImplementedError
def download_open(self, cmdline, pdfjs):
@@ -577,7 +586,8 @@ class LineEditPrompt(_BasePrompt):
self.setFocusProxy(self._lineedit)
self._init_key_label()
- def accept(self, value=None):
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
text = value if value is not None else self._lineedit.text()
self.question.answer = text
return True
@@ -693,7 +703,8 @@ class FilenamePrompt(_BasePrompt):
self._file_model.directoryLoaded.connect(
lambda: self._file_model.sort(0))
- def accept(self, value=None):
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
text = value if value is not None else self._lineedit.text()
text = downloads.transform_path(text)
if text is None:
@@ -763,8 +774,8 @@ class DownloadFilenamePrompt(FilenamePrompt):
super().__init__(question, parent)
self._file_model.setFilter(QDir.AllDirs | QDir.Drives | QDir.NoDot)
- def accept(self, value=None):
- done = super().accept(value)
+ def accept(self, value=None, save=False):
+ done = super().accept(value, save)
answer = self.question.answer
if answer is not None:
self.question.answer = downloads.FileDownloadTarget(answer)
@@ -817,7 +828,8 @@ class AuthenticationPrompt(_BasePrompt):
assert not question.default, question.default
self.setFocusProxy(self._user_lineedit)
- def accept(self, value=None):
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
if value is not None:
if ':' not in value:
raise Error("Value needs to be in the format "
@@ -860,7 +872,14 @@ class YesNoPrompt(_BasePrompt):
self._init_texts(question)
self._init_key_label()
- def accept(self, value=None):
+ def _check_save_support(self, save):
+ if self.question.option is None:
+ raise Error("No setting available to save the answer for this "
+ "question.")
+
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
+
if value is None:
if self.question.default is None:
raise Error("No default value was set for this question!")
@@ -871,14 +890,30 @@ class YesNoPrompt(_BasePrompt):
self.question.answer = False
else:
raise Error("Invalid value {} - expected yes/no!".format(value))
+
+ if save:
+ opt = config.instance.get_opt(self.question.option)
+ assert isinstance(opt.typ, configtypes.Bool)
+ pattern = urlmatch.UrlPattern(self.question.url)
+
+ try:
+ config.instance.set_obj(opt.name, self.question.answer,
+ pattern=pattern, save_yaml=True)
+ except configexc.Error as e:
+ raise Error(str(e))
+
return True
def _allowed_commands(self):
- cmds = [
- ('prompt-accept yes', "Yes"),
- ('prompt-accept no', "No"),
- ('prompt-yank', "Yank URL"),
- ]
+ cmds = []
+
+ cmds.append(('prompt-accept yes', "Yes"))
+ if self.question.option is not None:
+ cmds.append(('prompt-accept --save yes', "Always"))
+
+ cmds.append(('prompt-accept no', "No"))
+ if self.question.option is not None:
+ cmds.append(('prompt-accept --save no', "Never"))
if self.question.default is not None:
assert self.question.default in [True, False]
@@ -886,6 +921,7 @@ class YesNoPrompt(_BasePrompt):
cmds.append(('prompt-accept', "Use default ({})".format(default)))
cmds.append(('leave-mode', "Abort"))
+ cmds.append(('prompt-yank', "Yank URL"))
return cmds
@@ -898,7 +934,8 @@ class AlertPrompt(_BasePrompt):
self._init_texts(question)
self._init_key_label()
- def accept(self, value=None):
+ def accept(self, value=None, save=False):
+ self._check_save_support(save)
if value is not None:
raise Error("No value is permitted with alert prompts!")
# Simply mark prompt as done without setting self.question.answer