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:
parent
5ab052c40f
commit
5b4f6d39c2
@ -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):
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user