Remove CompletionModel.columns_to_filter.

Instead set this on inidividual categories, as that is where it actually
gets used. This makes it easier for SqlCompletionCategory to reuse a
prepared query (as it gets the filter field names in its constructor).
This commit is contained in:
Ryan Roden-Corrent 2017-05-29 22:58:11 -04:00
parent 8fb6f45bec
commit 2cd02be7b1
9 changed files with 35 additions and 24 deletions

View File

@ -197,7 +197,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
if index.parent().isValid(): if index.parent().isValid():
pattern = index.model().pattern pattern = index.model().pattern
columns_to_filter = index.model().columns_to_filter columns_to_filter = index.model().columns_to_filter(index)
if index.column() in columns_to_filter and pattern: if index.column() in columns_to_filter and pattern:
repl = r'<span class="highlight">\g<0></span>' repl = r'<span class="highlight">\g<0></span>'
text = re.sub(re.escape(pattern).replace(r'\ ', r'|'), text = re.sub(re.escape(pattern).replace(r'\ ', r'|'),

View File

@ -34,15 +34,13 @@ class CompletionModel(QAbstractItemModel):
Attributes: Attributes:
column_widths: The width percentages of the columns used in the column_widths: The width percentages of the columns used in the
completion view. completion view.
columns_to_filter: A list of indices of columns to apply the filter to.
pattern: Current filter pattern, used for highlighting. pattern: Current filter pattern, used for highlighting.
_categories: The sub-categories. _categories: The sub-categories.
""" """
def __init__(self, *, column_widths=(30, 70, 0), columns_to_filter=None, def __init__(self, *, column_widths=(30, 70, 0),
delete_cur_item=None, parent=None): delete_cur_item=None, parent=None):
super().__init__(parent) super().__init__(parent)
self.columns_to_filter = columns_to_filter or [0]
self.column_widths = column_widths self.column_widths = column_widths
self._categories = [] self._categories = []
self.pattern = '' self.pattern = ''
@ -173,8 +171,6 @@ class CompletionModel(QAbstractItemModel):
def set_pattern(self, pattern): def set_pattern(self, pattern):
"""Set the filter pattern for all categories. """Set the filter pattern for all categories.
This will apply to the fields indicated in columns_to_filter.
Args: Args:
pattern: The filter pattern to set. pattern: The filter pattern to set.
""" """
@ -182,7 +178,7 @@ class CompletionModel(QAbstractItemModel):
# TODO: should pattern be saved in the view layer instead? # TODO: should pattern be saved in the view layer instead?
self.pattern = pattern self.pattern = pattern
for cat in self._categories: for cat in self._categories:
cat.set_pattern(pattern, self.columns_to_filter) cat.set_pattern(pattern)
def first_item(self): def first_item(self):
"""Return the index of the first child (non-category) in the model.""" """Return the index of the first child (non-category) in the model."""
@ -204,3 +200,14 @@ class CompletionModel(QAbstractItemModel):
qtutils.ensure_valid(index) qtutils.ensure_valid(index)
return index return index
return QModelIndex() return QModelIndex()
def columns_to_filter(self, index):
"""Return the column indices the filter pattern applies to.
Args:
index: index of the item to check.
Return: A list of integers.
"""
cat = self._cat_from_idx(index.parent())
return cat.columns_to_filter if cat else []

View File

@ -35,25 +35,24 @@ class ListCategory(QSortFilterProxyModel):
"""Expose a list of items as a category for the CompletionModel.""" """Expose a list of items as a category for the CompletionModel."""
def __init__(self, name, items, parent=None): def __init__(self, name, items, columns_to_filter=None, parent=None):
super().__init__(parent) super().__init__(parent)
self.name = name self.name = name
self.srcmodel = QStandardItemModel(parent=self) self.srcmodel = QStandardItemModel(parent=self)
self.pattern = '' self.pattern = ''
self.pattern_re = None self.pattern_re = None
self.columns_to_filter = None self.columns_to_filter = columns_to_filter or [0]
for item in items: for item in items:
self.srcmodel.appendRow([QStandardItem(x) for x in item]) self.srcmodel.appendRow([QStandardItem(x) for x in item])
self.setSourceModel(self.srcmodel) self.setSourceModel(self.srcmodel)
def set_pattern(self, val, columns_to_filter): def set_pattern(self, val):
"""Setter for pattern. """Setter for pattern.
Args: Args:
val: The value to set. val: The value to set.
""" """
with debug.log_time(log.completion, 'Setting filter pattern'): with debug.log_time(log.completion, 'Setting filter pattern'):
self.columns_to_filter = columns_to_filter
self.pattern = val self.pattern = val
val = re.sub(r' +', r' ', val) # See #1919 val = re.sub(r' +', r' ', val) # See #1919
val = re.escape(val) val = re.escape(val)

View File

@ -110,8 +110,7 @@ def buffer():
model = completionmodel.CompletionModel( model = completionmodel.CompletionModel(
column_widths=(6, 40, 54), column_widths=(6, 40, 54),
delete_cur_item=delete_buffer, delete_cur_item=delete_buffer)
columns_to_filter=[idx_column, url_column, text_column])
for win_id in objreg.window_registry: for win_id in objreg.window_registry:
tabbed_browser = objreg.get('tabbed-browser', scope='window', tabbed_browser = objreg.get('tabbed-browser', scope='window',
@ -124,8 +123,10 @@ def buffer():
tabs.append(("{}/{}".format(win_id, idx + 1), tabs.append(("{}/{}".format(win_id, idx + 1),
tab.url().toDisplayString(), tab.url().toDisplayString(),
tabbed_browser.page_title(idx))) tabbed_browser.page_title(idx)))
cat = listcategory.ListCategory("{}".format(win_id), tabs) cat = listcategory.ListCategory("{}".format(win_id), tabs,
columns_to_filter=[idx_column, url_column, text_column])
model.add_category(cat) model.add_category(cat)
return model return model

View File

@ -61,8 +61,11 @@ class SqlCategory(QSqlQueryModel):
self._query = sql.Query(querystr) self._query = sql.Query(querystr)
self._param_count = len(filter_fields) self._param_count = len(filter_fields)
rec = self._query.record()
# will this work?
self.columns_to_filter = [rec.indexOf(n) for n in filter_fields]
def set_pattern(self, pattern, _columns_to_filter=None): def set_pattern(self, pattern):
"""Set the pattern used to filter results. """Set the pattern used to filter results.
Args: Args:

View File

@ -63,15 +63,16 @@ def url():
""" """
model = completionmodel.CompletionModel( model = completionmodel.CompletionModel(
column_widths=(40, 50, 10), column_widths=(40, 50, 10),
columns_to_filter=[_URLCOL, _TEXTCOL],
delete_cur_item=_delete_url) delete_cur_item=_delete_url)
quickmarks = ((url, name) for (name, url) quickmarks = ((url, name) for (name, url)
in objreg.get('quickmark-manager').marks.items()) in objreg.get('quickmark-manager').marks.items())
bookmarks = objreg.get('bookmark-manager').marks.items() bookmarks = objreg.get('bookmark-manager').marks.items()
model.add_category(listcategory.ListCategory('Quickmarks', quickmarks)) model.add_category(listcategory.ListCategory('Quickmarks', quickmarks,
model.add_category(listcategory.ListCategory('Bookmarks', bookmarks)) columns_to_filter=[0, 1]))
model.add_category(listcategory.ListCategory('Bookmarks', bookmarks,
columns_to_filter=[0, 1]))
timefmt = config.get('completion', 'timestamp-format') timefmt = config.get('completion', 'timestamp-format')
select_time = "strftime('{}', max(atime), 'unixepoch')".format(timefmt) select_time = "strftime('{}', max(atime), 'unixepoch')".format(timefmt)

View File

@ -65,11 +65,10 @@ def test_count(counts):
@hypothesis.given(strategies.text()) @hypothesis.given(strategies.text())
def test_set_pattern(pat): def test_set_pattern(pat):
"""Validate the filtering and sorting results of set_pattern.""" """Validate the filtering and sorting results of set_pattern."""
cols = [1, 2, 3] model = completionmodel.CompletionModel()
model = completionmodel.CompletionModel(columns_to_filter=cols)
cats = [mock.Mock(spec=['set_pattern'])] * 3 cats = [mock.Mock(spec=['set_pattern'])] * 3
for c in cats: for c in cats:
c.set_pattern = mock.Mock() c.set_pattern = mock.Mock()
model.add_category(c) model.add_category(c)
model.set_pattern(pat) model.set_pattern(pat)
assert all(c.set_pattern.called_with([pat, cols]) for c in cats) assert all(c.set_pattern.called_with([pat]) for c in cats)

View File

@ -65,6 +65,7 @@ def _validate(cat, expected):
]) ])
def test_set_pattern(pattern, filter_cols, before, after): def test_set_pattern(pattern, filter_cols, before, after):
"""Validate the filtering and sorting results of set_pattern.""" """Validate the filtering and sorting results of set_pattern."""
cat = listcategory.ListCategory('Foo', before) cat = listcategory.ListCategory('Foo', before,
cat.set_pattern(pattern, filter_cols) columns_to_filter=filter_cols)
cat.set_pattern(pattern)
_validate(cat, after) _validate(cat, after)

View File

@ -132,7 +132,7 @@ def test_set_pattern(pattern, filter_cols, before, after):
table.insert(row) table.insert(row)
filter_fields = [['a', 'b', 'c'][i] for i in filter_cols] filter_fields = [['a', 'b', 'c'][i] for i in filter_cols]
cat = sqlcategory.SqlCategory('Foo', filter_fields=filter_fields) cat = sqlcategory.SqlCategory('Foo', filter_fields=filter_fields)
cat.set_pattern(pattern, filter_cols) cat.set_pattern(pattern)
_validate(cat, after) _validate(cat, after)