From 4e793180c1de4883948b9cb7d3e9279b19e8d653 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 31 Oct 2016 13:53:55 +0100 Subject: [PATCH] Fix completion in file prompts --- qutebrowser/mainwindow/prompt.py | 22 +++++++++--- tests/unit/mainwindow/test_prompt.py | 53 ++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 tests/unit/mainwindow/test_prompt.py diff --git a/qutebrowser/mainwindow/prompt.py b/qutebrowser/mainwindow/prompt.py index f96bf615b..4e4c4c550 100644 --- a/qutebrowser/mainwindow/prompt.py +++ b/qutebrowser/mainwindow/prompt.py @@ -599,6 +599,11 @@ class FilenamePrompt(_BasePrompt): self._file_view.setHeaderHidden(True) for col in range(1, 4): self._file_view.setColumnHidden(col, True) + # Nothing selected initially + self._file_view.setCurrentIndex(QModelIndex()) + # The model needs to be sorted so we get the correct first/last index + self._file_model.directoryLoaded.connect( + lambda: self._file_model.sort(0)) def accept(self, value=None): text = value if value is not None else self._lineedit.text() @@ -610,18 +615,27 @@ class FilenamePrompt(_BasePrompt): assert which in ['prev', 'next'], which selmodel = self._file_view.selectionModel() - first_index = self._file_model.index(0, 0) - last_index = self._file_model.index(self._file_model.rowCount() - 1, 0) + parent = self._file_view.rootIndex() + first_index = self._file_model.index(0, 0, parent) + row = self._file_model.rowCount(parent) - 1 + last_index = self._file_model.index(row, 0, parent) + + if not first_index.isValid(): + # No entries + return + + assert last_index.isValid() idx = selmodel.currentIndex() if not idx.isValid(): # No item selected yet idx = last_index if which == 'prev' else first_index - - if which == 'prev': + elif which == 'prev': idx = self._file_view.indexAbove(idx) else: + assert which == 'next', which idx = self._file_view.indexBelow(idx) + # wrap around if we arrived at beginning/end if not idx.isValid(): idx = last_index if which == 'prev' else first_index diff --git a/tests/unit/mainwindow/test_prompt.py b/tests/unit/mainwindow/test_prompt.py new file mode 100644 index 000000000..6d50a515d --- /dev/null +++ b/tests/unit/mainwindow/test_prompt.py @@ -0,0 +1,53 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2016 Florian Bruhin (The Compiler) +# +# 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 . + +import pytest + +from qutebrowser.mainwindow import prompt as promptmod +from qutebrowser.utils import usertypes + + +@pytest.fixture(autouse=True) +def setup(qapp, key_config_stub): + key_config_stub.set_bindings_for('prompt', {}) + + +@pytest.mark.parametrize('steps, where, subfolder', [ + (1, 'next', '..'), + (1, 'prev', 'c'), + (2, 'next', 'a'), + (2, 'prev', 'b'), +]) +def test_file_completion(tmpdir, qtbot, steps, where, subfolder): + for directory in 'abc': + (tmpdir / directory).ensure(dir=True) + question = usertypes.Question() + question.title = "test" + question.default = str(tmpdir) + '/' + + prompt = promptmod.DownloadFilenamePrompt(question) + qtbot.add_widget(prompt) + with qtbot.wait_signal(prompt._file_model.directoryLoaded): + pass + assert prompt._lineedit.text() == str(tmpdir) + '/' + + for _ in range(steps): + prompt.item_focus(where) + + assert prompt._lineedit.text() == str(tmpdir / subfolder)