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