Fix mode handling with multiple javascript prompts.

This fixes a regression introduced in 03ac8874ff.
This commit is contained in:
Florian Bruhin 2014-12-28 01:27:18 +01:00
parent 177707687c
commit 73d08cb60c
2 changed files with 32 additions and 22 deletions

View File

@ -254,7 +254,9 @@ class ModeManager(QObject):
mode, '' if reason is None else ' (reason: {})'.format(reason)))
if mode not in self._handlers:
raise ValueError("No handler for mode {}".format(mode))
if self.mode == mode:
prompt_modes = (usertypes.KeyMode.prompt, usertypes.KeyMode.yesno)
if self.mode == mode or (self.mode in prompt_modes and
mode in prompt_modes):
log.modes.debug("Ignoring request as we're in mode {} "
"already.".format(self.mode))
return

View File

@ -57,6 +57,9 @@ class Prompter(QObject):
things happen is clear, e.g. on_mode_left can't happen after we already set
up the *new* question.
Class Attributes:
KEY_MODES: A mapping of PromptModes to KeyModes.
Attributes:
_shutting_down: Whether we're currently shutting down the prompter and
should ignore future questions to avoid segfaults.
@ -71,6 +74,13 @@ class Prompter(QObject):
hide_prompt: Emitted when the prompt widget should be hidden.
"""
KEY_MODES = {
usertypes.PromptMode.yesno: usertypes.KeyMode.yesno,
usertypes.PromptMode.text: usertypes.KeyMode.prompt,
usertypes.PromptMode.user_pwd: usertypes.KeyMode.prompt,
usertypes.PromptMode.alert: usertypes.KeyMode.prompt,
}
show_prompt = pyqtSignal()
hide_prompt = pyqtSignal()
@ -135,14 +145,14 @@ class Prompter(QObject):
prompt.lineedit.setEchoMode(ctx.echo_mode)
prompt.lineedit.setVisible(ctx.input_visible)
self.show_prompt.emit()
mode = self.KEY_MODES[ctx.question.mode]
ctx.question.aborted.connect(
lambda: modeman.maybe_leave(self._win_id, mode, 'aborted'))
modeman.enter(self._win_id, mode, 'question asked')
return True
def _display_question(self):
"""Display the question saved in self._question.
Return:
The mode which should be entered.
"""
"""Display the question saved in self._question."""
prompt = objreg.get('prompt', scope='window', window=self._win_id)
if self._question.mode == usertypes.PromptMode.yesno:
if self._question.default is None:
@ -153,23 +163,19 @@ class Prompter(QObject):
suffix = " (no)"
prompt.txt.setText(self._question.text + suffix)
prompt.lineedit.hide()
mode = usertypes.KeyMode.yesno
elif self._question.mode == usertypes.PromptMode.text:
prompt.txt.setText(self._question.text)
if self._question.default:
prompt.lineedit.setText(self._question.default)
prompt.lineedit.show()
mode = usertypes.KeyMode.prompt
elif self._question.mode == usertypes.PromptMode.user_pwd:
prompt.txt.setText(self._question.text)
if self._question.default:
prompt.lineedit.setText(self._question.default)
prompt.lineedit.show()
mode = usertypes.KeyMode.prompt
elif self._question.mode == usertypes.PromptMode.alert:
prompt.txt.setText(self._question.text + ' (ok)')
prompt.lineedit.hide()
mode = usertypes.KeyMode.prompt
else:
raise ValueError("Invalid prompt mode!")
log.modes.debug("Question asked, focusing {!r}".format(
@ -177,7 +183,6 @@ class Prompter(QObject):
prompt.lineedit.setFocus()
self.show_prompt.emit()
self._busy = True
return mode
def shutdown(self):
"""Cancel all blocking questions.
@ -233,25 +238,25 @@ class Prompter(QObject):
# User just entered a password
password = prompt.lineedit.text()
self._question.answer = (self._question.user, password)
modeman.leave(self._win_id, usertypes.KeyMode.prompt,
modeman.maybe_leave(self._win_id, usertypes.KeyMode.prompt,
'prompt accept')
self._question.done()
elif self._question.mode == usertypes.PromptMode.text:
# User just entered text.
self._question.answer = prompt.lineedit.text()
modeman.leave(self._win_id, usertypes.KeyMode.prompt,
modeman.maybe_leave(self._win_id, usertypes.KeyMode.prompt,
'prompt accept')
self._question.done()
elif self._question.mode == usertypes.PromptMode.yesno:
# User wants to accept the default of a yes/no question.
self._question.answer = self._question.default
modeman.leave(self._win_id, usertypes.KeyMode.yesno,
modeman.maybe_leave(self._win_id, usertypes.KeyMode.yesno,
'yesno accept')
self._question.done()
elif self._question.mode == usertypes.PromptMode.alert:
# User acknowledged an alert
self._question.answer = None
modeman.leave(self._win_id, usertypes.KeyMode.prompt,
modeman.maybe_leave(self._win_id, usertypes.KeyMode.prompt,
'alert accept')
self._question.done()
else:
@ -265,7 +270,8 @@ class Prompter(QObject):
# We just ignore this if we don't have a yes/no question.
return
self._question.answer = True
modeman.leave(self._win_id, usertypes.KeyMode.yesno, 'yesno accept')
modeman.maybe_leave(self._win_id, usertypes.KeyMode.yesno,
'yesno accept')
self._question.done()
@cmdutils.register(instance='prompter', hide=True, scope='window',
@ -276,7 +282,8 @@ class Prompter(QObject):
# We just ignore this if we don't have a yes/no question.
return
self._question.answer = False
modeman.leave(self._win_id, usertypes.KeyMode.yesno, 'prompt accept')
modeman.maybe_leave(self._win_id, usertypes.KeyMode.yesno,
'prompt accept')
self._question.done()
@pyqtSlot(usertypes.Question, bool)
@ -317,7 +324,8 @@ class Prompter(QObject):
context = self._get_ctx()
self._question = question
mode = self._display_question()
self._display_question()
mode = self.KEY_MODES[self._question.mode]
question.aborted.connect(
lambda: modeman.maybe_leave(self._win_id, mode, 'aborted'))
modeman.enter(self._win_id, mode, 'question asked')