def test_normal_exec(self): """Test exec_ without double-executing.""" self.loop = qtutils.EventLoop() QTimer.singleShot(100, self._assert_executing) QTimer.singleShot(200, self.loop.quit) self.loop.exec_() assert not self.loop._executing
def _execute_fileselect_command( command: List[str], qb_mode: FileSelectionMode, tmpfilename: Optional[str] = None ) -> List[str]: """Execute external command to choose file. Args: multiple: Should selecting multiple files be allowed. tmpfilename: Path to the temporary file if used, otherwise None. Return: A list of selected file paths, or empty list if no file is selected. If multiple is False, the return value will have at most 1 item. """ proc = guiprocess.GUIProcess(what='choose-file') proc.start(command[0], command[1:]) loop = qtutils.EventLoop() proc.finished.connect(lambda _code, _status: loop.exit()) loop.exec() if tmpfilename is None: selected_files = proc.stdout.splitlines() else: try: with open(tmpfilename, mode='r', encoding=sys.getfilesystemencoding()) as f: selected_files = f.read().splitlines() except OSError as e: message.error(f"Failed to open tempfile {tmpfilename} ({e})!") selected_files = [] return list(_validated_selected_files( qb_mode=qb_mode, selected_files=selected_files))
def test_double_exec(self): """Test double-executing.""" self.loop = qtutils.EventLoop() QTimer.singleShot(100, self._assert_executing) QTimer.singleShot(200, self._double_exec) QTimer.singleShot(300, self._assert_executing) QTimer.singleShot(400, self.loop.quit) self.loop.exec_() assert not self.loop._executing
def ask_question(self, question, blocking): """Dispkay a question in the statusbar. Args: question: The Question object to ask. blocking: If True, this function blocks and returns the result. Return: The answer of the user when blocking=True. None if blocking=False. """ log.statusbar.debug("Asking question {}, blocking {}, loops {}, queue " "{}".format(question, blocking, self._loops, self._queue)) if self._shutting_down: # If we're currently shutting down we have to ignore this question # to avoid segfaults - see # https://github.com/The-Compiler/qutebrowser/issues/95 log.statusbar.debug("Ignoring question because we're shutting " "down.") question.abort() return None if self._busy and not blocking: # We got an async question, but we're already busy with one, so we # just queue it up for later. log.statusbar.debug("Adding {} to queue.".format(question)) self._queue.append(question) return if blocking: # If we're blocking we save the old state on the stack, so we can # restore it after exec, if exec gets called multiple times. context = self._get_ctx() self._question = 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') if blocking: loop = qtutils.EventLoop() self._loops.append(loop) loop.destroyed.connect(lambda: self._loops.remove(loop)) question.completed.connect(loop.quit) question.completed.connect(loop.deleteLater) loop.exec_() if not self._restore_ctx(context): # Nothing left to restore, so we can go back to popping async # questions. if self._queue: self._pop_later() return self._question.answer else: question.completed.connect(self._pop_later)
def ask_question(self, question, blocking): """Dispkay a question in the statusbar. Args: question: The Question object to ask. blocking: If True, this function blocks and returns the result. Return: The answer of the user when blocking=True. None if blocking=False. """ log.statusbar.debug("Asking question {}, blocking {}, loops {}, queue " "{}".format(question, blocking, self._loops, self._queue)) if self._busy and not blocking: # We got an async question, but we're already busy with one, so we # just queue it up for later. log.statusbar.debug("Adding {} to queue.".format(question)) self._queue.append(question) return if blocking: # If we're blocking we save the old state on the stack, so we can # restore it after exec, if exec gets called multiple times. context = self._get_ctx() self._question = question mode = self._display_question() question.aborted.connect( lambda: modeman.maybe_leave(self._win_id, mode, 'aborted')) mode_manager = objreg.get('mode-manager', scope='window', window=self._win_id) try: modeman.enter(self._win_id, mode, 'question asked', override=True) except modeman.ModeLockedError: if mode_manager.mode() != usertypes.KeyMode.prompt: question.abort() return None mode_manager.locked = True if blocking: loop = qtutils.EventLoop() self._loops.append(loop) loop.destroyed.connect(lambda: self._loops.remove(loop)) question.completed.connect(loop.quit) question.completed.connect(loop.deleteLater) loop.exec_() if not self._restore_ctx(context): # Nothing left to restore, so we can go back to popping async # questions. if self._queue: self._pop_later() return self._question.answer else: question.completed.connect(self._pop_later)
def choose_file(multiple: bool) -> List[str]: """Select file(s) for uploading, using external command defined in config. Args: multiple: Should selecting multiple files be allowed. Return: A list of selected file paths, or empty list if no file is selected. If multiple is False, the return value will have at most 1 item. """ handle = tempfile.NamedTemporaryFile(prefix='qutebrowser-fileselect-', delete=False) handle.close() tmpfilename = handle.name with utils.cleanup_file(tmpfilename): if multiple: command = config.val.fileselect.multiple_files.command else: command = config.val.fileselect.single_file.command proc = guiprocess.GUIProcess(what='choose-file') proc.start(command[0], [arg.replace('{}', tmpfilename) for arg in command[1:]]) loop = qtutils.EventLoop() proc.finished.connect(lambda _code, _status: loop.exit()) loop.exec() try: with open(tmpfilename, mode='r', encoding=sys.getfilesystemencoding()) as f: selected_files = f.read().splitlines() except OSError as e: message.error(f"Failed to open tempfile {tmpfilename} ({e})!") selected_files = [] if not multiple: if len(selected_files) > 1: message.warning("More than one file chosen, using only the first") return selected_files[:1] return selected_files
def ask_question(self, question, blocking): """Display a prompt for a given question. Args: question: The Question object to ask. blocking: If True, this function blocks and returns the result. Return: The answer of the user when blocking=True. None if blocking=False. """ log.prompt.debug("Asking question {}, blocking {}, loops {}, queue " "{}".format(question, blocking, self._loops, self._queue)) if self._shutting_down: # If we're currently shutting down we have to ignore this question # to avoid segfaults - see # https://github.com/qutebrowser/qutebrowser/issues/95 log.prompt.debug("Ignoring question because we're shutting down.") question.abort() return None if self._question is not None and not blocking: # We got an async question, but we're already busy with one, so we # just queue it up for later. log.prompt.debug("Adding {} to queue.".format(question)) self._queue.append(question) return None if blocking: # If we're blocking we save the old question on the stack, so we # can restore it after exec, if exec gets called multiple times. log.prompt.debug("New question is blocking, saving {}".format( self._question)) old_question = self._question if old_question is not None: old_question.interrupted = True self._question = question self.show_prompts.emit(question) if blocking: loop = qtutils.EventLoop() self._loops.append(loop) loop.destroyed.connect(lambda: self._loops.remove(loop)) question.completed.connect(loop.quit) question.completed.connect(loop.deleteLater) log.prompt.debug("Starting loop.exec_() for {}".format(question)) flags = cast(QEventLoop.ProcessEventsFlags, QEventLoop.ExcludeSocketNotifiers) loop.exec_(flags) log.prompt.debug("Ending loop.exec_() for {}".format(question)) log.prompt.debug("Restoring old question {}".format(old_question)) self._question = old_question self.show_prompts.emit(old_question) if old_question is None: # Nothing left to restore, so we can go back to popping async # questions. if self._queue: self._pop_later() return question.answer else: question.completed.connect(self._pop_later) return None
def _wait(self): """Wait until a reply from the remote server is received.""" if self._manager is not None: loop = qtutils.EventLoop() self.finished.connect(loop.quit) loop.exec_()