Add a dumb sorting option to CompletionFilterModel.

This makes it possible to use Qt's QSortFilterProxyModel::lessThan option for
completions where it doesn't make sense to priorize matches starting with the
entered string, e.g. for URLs. In return, we get a *much* better performance
(several seconds when opening the completion).

See #531.
This commit is contained in:
Florian Bruhin 2015-03-11 07:16:23 +01:00
parent 5ab052c40f
commit 5b4f6d39c2
2 changed files with 21 additions and 4 deletions

View File

@ -60,7 +60,7 @@ class BaseCompletionModel(QStandardItemModel):
self.appendRow(cat)
return cat
def new_item(self, cat, name, desc='', misc=None):
def new_item(self, cat, name, desc='', misc=None, sort=None):
"""Add a new item to a category.
Args:
@ -68,6 +68,7 @@ class BaseCompletionModel(QStandardItemModel):
name: The name of the item.
desc: The description of the item.
misc: Misc text to display.
sort: Data for the sort role (int).
Return:
A (nameitem, descitem, miscitem) tuple.
@ -82,6 +83,8 @@ class BaseCompletionModel(QStandardItemModel):
cat.setChild(idx, 0, nameitem)
cat.setChild(idx, 1, descitem)
cat.setChild(idx, 2, miscitem)
if sort is not None:
nameitem.setData(sort, Role.sort)
return nameitem, descitem, miscitem
def flags(self, index):

View File

@ -23,7 +23,7 @@ Contains:
CompletionFilterModel -- A QSortFilterProxyModel subclass for completions.
"""
from PyQt5.QtCore import QSortFilterProxyModel, QModelIndex
from PyQt5.QtCore import QSortFilterProxyModel, QModelIndex, Qt
from qutebrowser.utils import log, qtutils
from qutebrowser.completion.models import base as completion
@ -38,13 +38,21 @@ class CompletionFilterModel(QSortFilterProxyModel):
srcmodel: The current source model.
Kept as attribute because calling `sourceModel` takes quite
a long time for some reason.
_sort_order: The order to use for sorting if using dumb_sort.
"""
def __init__(self, source, parent=None):
def __init__(self, source, parent=None, *, dumb_sort=None):
super().__init__(parent)
super().setSourceModel(source)
self.srcmodel = source
self.pattern = ''
if dumb_sort is None:
# pylint: disable=invalid-name
self.lessThan = self.intelligentLessThan
self._sort_order = Qt.AscendingOrder
else:
self.setSortRole(completion.Role.sort)
self._sort_order = dumb_sort
def set_pattern(self, val):
"""Setter for pattern.
@ -131,7 +139,7 @@ class CompletionFilterModel(QSortFilterProxyModel):
return True
return self.pattern.casefold() in data.casefold()
def lessThan(self, lindex, rindex):
def intelligentLessThan(self, lindex, rindex):
"""Custom sorting implementation.
Prefers all items which start with self.pattern. Other than that, uses
@ -167,3 +175,9 @@ class CompletionFilterModel(QSortFilterProxyModel):
return False
else:
return left < right
def sort(self, column, order=None):
"""Extend sort to respect self._sort_order if no order was given."""
if order is None:
order = self._sort_order
super().sort(column, order)