2014-05-19 17:01:05 +02:00
|
|
|
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
|
|
|
#
|
|
|
|
# This file is part of qutebrowser.
|
|
|
|
#
|
|
|
|
# qutebrowser is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# qutebrowser is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
"""Prompt shown in the statusbar."""
|
|
|
|
|
2014-05-19 17:36:31 +02:00
|
|
|
from PyQt5.QtCore import pyqtSignal, QEventLoop, QObject
|
2014-05-19 17:01:05 +02:00
|
|
|
from PyQt5.QtWidgets import QLineEdit, QHBoxLayout
|
|
|
|
|
|
|
|
import qutebrowser.keyinput.modeman as modeman
|
|
|
|
import qutebrowser.commands.utils as cmdutils
|
|
|
|
from qutebrowser.widgets.statusbar._textbase import TextBase
|
|
|
|
from qutebrowser.utils.usertypes import enum
|
|
|
|
|
|
|
|
PromptMode = enum('yesno', 'text', 'user_pwd')
|
|
|
|
|
|
|
|
|
2014-05-19 17:36:31 +02:00
|
|
|
class Question(QObject):
|
2014-05-19 17:01:05 +02:00
|
|
|
|
2014-05-19 17:36:31 +02:00
|
|
|
answered = pyqtSignal()
|
2014-05-19 17:01:05 +02:00
|
|
|
|
|
|
|
def __init__(self, parent=None):
|
|
|
|
super().__init__(parent)
|
|
|
|
self.mode = None
|
|
|
|
self.default = None
|
|
|
|
self.text = None
|
2014-05-19 17:43:31 +02:00
|
|
|
self.user = None
|
2014-05-19 17:36:31 +02:00
|
|
|
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):
|
|
|
|
|
|
|
|
show_prompt = pyqtSignal()
|
|
|
|
hide_prompt = pyqtSignal()
|
2014-05-19 17:57:58 +02:00
|
|
|
cancelled = pyqtSignal()
|
2014-05-19 17:01:05 +02:00
|
|
|
|
2014-05-19 17:36:31 +02:00
|
|
|
def __init__(self, parent=None):
|
|
|
|
super().__init__(parent)
|
|
|
|
|
|
|
|
self.question = None
|
2014-05-19 17:01:05 +02:00
|
|
|
self.loop = QEventLoop()
|
|
|
|
|
|
|
|
self._hbox = QHBoxLayout(self)
|
|
|
|
self._hbox.setContentsMargins(0, 0, 0, 0)
|
|
|
|
self._hbox.setSpacing(5)
|
|
|
|
|
|
|
|
self._txt = TextBase()
|
|
|
|
self._hbox.addWidget(self._txt)
|
|
|
|
|
|
|
|
self._input = _QueryInput()
|
|
|
|
self._hbox.addWidget(self._input)
|
|
|
|
|
2014-05-19 17:36:31 +02:00
|
|
|
def on_mode_left(self, mode):
|
|
|
|
if mode == 'prompt':
|
|
|
|
self._txt.setText('')
|
|
|
|
self._input.clear()
|
|
|
|
self._input.setEchoMode(QLineEdit.Normal)
|
|
|
|
self.hide_prompt.emit()
|
2014-05-19 17:57:58 +02:00
|
|
|
if self.question.answer is None:
|
|
|
|
self.cancelled.emit()
|
2014-05-19 17:01:05 +02:00
|
|
|
|
|
|
|
@cmdutils.register(instance='mainwindow.status.prompt', hide=True,
|
|
|
|
modes=['prompt'])
|
|
|
|
def prompt_accept(self):
|
|
|
|
"""Accept the prompt. """
|
2014-05-19 17:43:31 +02:00
|
|
|
if (self.question.mode == PromptMode.user_pwd and
|
|
|
|
self.question.user is None):
|
2014-05-19 17:41:42 +02:00
|
|
|
# User just entered an username
|
2014-05-19 17:43:31 +02:00
|
|
|
self.question.user = self._input.text()
|
2014-05-19 17:41:42 +02:00
|
|
|
self._txt.setText("Password:")
|
|
|
|
self._input.clear()
|
|
|
|
self._input.setEchoMode(QLineEdit.Password)
|
|
|
|
elif self.question.mode == PromptMode.user_pwd:
|
|
|
|
# User just entered a password
|
|
|
|
password = self._input.text()
|
2014-05-19 17:43:31 +02:00
|
|
|
self.question.answer = (self.question.user, password)
|
2014-05-19 17:41:42 +02:00
|
|
|
modeman.leave('prompt', 'prompt accept')
|
|
|
|
self.hide_prompt.emit()
|
|
|
|
else:
|
|
|
|
# User just entered all information needed in some other mode.
|
|
|
|
self.question.answer = self._input.text()
|
|
|
|
modeman.leave('prompt', 'prompt accept')
|
2014-05-19 17:01:05 +02:00
|
|
|
|
|
|
|
def display(self):
|
2014-05-19 17:36:31 +02:00
|
|
|
q = self.question
|
|
|
|
if q.mode == PromptMode.yesno:
|
|
|
|
if q.default is None:
|
2014-05-19 17:01:05 +02:00
|
|
|
suffix = " [y/n]"
|
2014-05-19 17:36:31 +02:00
|
|
|
elif q.default:
|
2014-05-19 17:01:05 +02:00
|
|
|
suffix = " [Y/n]"
|
|
|
|
else:
|
|
|
|
suffix = " [y/N]"
|
2014-05-19 17:36:31 +02:00
|
|
|
self._txt.setText(q.text + suffix)
|
2014-05-19 17:01:05 +02:00
|
|
|
self._input.hide()
|
2014-05-19 17:36:31 +02:00
|
|
|
elif q.mode == PromptMode.text:
|
|
|
|
self._txt.setText(q.text)
|
|
|
|
if q.default:
|
|
|
|
self._input.setText(q.default)
|
2014-05-19 17:01:05 +02:00
|
|
|
self._input.show()
|
2014-05-19 17:36:31 +02:00
|
|
|
elif q.mode == PromptMode.user_pwd:
|
|
|
|
self._txt.setText(q.text)
|
|
|
|
if q.default:
|
|
|
|
self._input.setText(q.default)
|
2014-05-19 17:01:05 +02:00
|
|
|
self._input.show()
|
|
|
|
else:
|
|
|
|
raise ValueError("Invalid prompt mode!")
|
|
|
|
self._input.setFocus()
|
2014-05-19 17:36:31 +02:00
|
|
|
self.show_prompt.emit()
|
2014-05-19 17:01:05 +02:00
|
|
|
|
|
|
|
def exec_(self):
|
|
|
|
self.display()
|
2014-05-19 17:36:31 +02:00
|
|
|
self.question.answered.connect(self.loop.quit)
|
2014-05-19 17:57:58 +02:00
|
|
|
self.cancelled.connect(self.loop.quit)
|
2014-05-19 17:01:05 +02:00
|
|
|
self.loop.exec_()
|
2014-05-19 17:36:31 +02:00
|
|
|
return self.question.answer
|
2014-05-19 17:01:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
class _QueryInput(QLineEdit):
|
|
|
|
|
|
|
|
"""Minimal QLineEdit used for input."""
|
|
|
|
|
|
|
|
def __init__(self, parent=None):
|
|
|
|
super().__init__(parent)
|
|
|
|
self.setStyleSheet("""
|
|
|
|
QLineEdit {
|
|
|
|
border: 0px;
|
|
|
|
padding-left: 1px;
|
|
|
|
background-color: transparent;
|
|
|
|
}
|
|
|
|
""")
|
|
|
|
|
|
|
|
def focusInEvent(self, e):
|
|
|
|
"""Extend focusInEvent to enter command mode."""
|
|
|
|
modeman.enter('prompt', 'auth focus')
|
|
|
|
super().focusInEvent(e)
|