Use builtin SortFilter regex functionality.

With the new completion API, we no longer need a custom filterAcceptsRow
function. This was necessary to handle the tree structure of the model,
but now we use a separate QSortFilterProxyModel for each category, so
the data it filters is flat. We can simplify the code by using the
builtin setFilterRegExp.

This changes the behavior a little, as now all list categories filter on
all columns. This should be beneficial if anything. For example, help
topics are now filtered on description in addition to name.

This also seems to slightly speed up filtering, according to the url
model benchmark.

Before:

----------------------------------------------- benchmark: 1 tests ----------------------------------------------
Name (time in s)                     Min     Max    Mean  StdDev  Median     IQR  Outliers(*)  Rounds  Iterations
-----------------------------------------------------------------------------------------------------------------
test_url_completion_benchmark     1.2806  1.3817  1.3195  0.0390  1.3068  0.0487          1;0       5           1
-----------------------------------------------------------------------------------------------------------------

After:

----------------------------------------------- benchmark: 1 tests ----------------------------------------------
Name (time in s)                     Min     Max    Mean  StdDev  Median     IQR  Outliers(*)  Rounds  Iterations
-----------------------------------------------------------------------------------------------------------------
test_url_completion_benchmark     1.1183  1.1508  1.1281  0.0132  1.1241  0.0142          1;0       5           1
-----------------------------------------------------------------------------------------------------------------
This commit is contained in:
Ryan Roden-Corrent 2017-06-29 12:44:02 -04:00
parent 6ac940fa32
commit 9c0c174534
3 changed files with 9 additions and 41 deletions

View File

@ -21,7 +21,7 @@
import re
from PyQt5.QtCore import QSortFilterProxyModel, QModelIndex
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QModelIndex, QRegExp
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from qutebrowser.utils import qtutils
@ -32,14 +32,14 @@ class ListCategory(QSortFilterProxyModel):
"""Expose a list of items as a category for the CompletionModel."""
def __init__(self, name, items, columns_to_filter=None,
delete_func=None, parent=None):
def __init__(self, name, items, delete_func=None, parent=None):
super().__init__(parent)
self.name = name
self.srcmodel = QStandardItemModel(parent=self)
self.pattern = ''
self.pattern_re = None
self.columns_to_filter = columns_to_filter or [0]
# ListCategory filters all columns
self.columns_to_filter = [0, 1, 2]
self.setFilterKeyColumn(-1)
for item in items:
self.srcmodel.appendRow([QStandardItem(x) for x in item])
self.setSourceModel(self.srcmodel)
@ -55,38 +55,12 @@ class ListCategory(QSortFilterProxyModel):
val = re.sub(r' +', r' ', val) # See #1919
val = re.escape(val)
val = val.replace(r'\ ', '.*')
self.pattern_re = re.compile(val, re.IGNORECASE)
rx = QRegExp(val, Qt.CaseInsensitive)
self.setFilterRegExp(rx)
self.invalidate()
sortcol = 0
self.sort(sortcol)
def filterAcceptsRow(self, row, parent):
"""Custom filter implementation.
Override QSortFilterProxyModel::filterAcceptsRow.
Args:
row: The row of the item.
parent: The parent item QModelIndex.
Return:
True if self.pattern is contained in item.
"""
if not self.pattern:
return True
for col in self.columns_to_filter:
idx = self.srcmodel.index(row, col, parent)
if not idx.isValid(): # pragma: no cover
# this is a sanity check not hit by any test case
continue
data = self.srcmodel.data(idx)
if not data:
continue
elif self.pattern_re.search(data):
return True
return False
def lessThan(self, lindex, rindex):
"""Custom sorting implementation.

View File

@ -92,9 +92,6 @@ def buffer():
Used for switching the buffer command.
"""
idx_column = 0
url_column = 1
text_column = 2
def delete_buffer(data):
"""Close the selected tab."""
@ -117,7 +114,6 @@ def buffer():
tab.url().toDisplayString(),
tabbed_browser.page_title(idx)))
cat = listcategory.ListCategory("{}".format(win_id), tabs,
columns_to_filter=[idx_column, url_column, text_column],
delete_func=delete_buffer)
model.add_category(cat)

View File

@ -62,11 +62,9 @@ def url():
bookmarks = objreg.get('bookmark-manager').marks.items()
model.add_category(listcategory.ListCategory(
'Quickmarks', quickmarks, columns_to_filter=[0, 1],
delete_func=_delete_quickmark))
'Quickmarks', quickmarks, delete_func=_delete_quickmark))
model.add_category(listcategory.ListCategory(
'Bookmarks', bookmarks, columns_to_filter=[0, 1],
delete_func=_delete_bookmark))
'Bookmarks', bookmarks, delete_func=_delete_bookmark))
# replace 's to avoid breaking the query
timefmt = config.get('completion', 'timestamp-format').replace("'", "`")