Move models to qutebrowser.models

This commit is contained in:
Florian Bruhin 2014-02-14 17:41:12 +01:00
parent 302736925b
commit 933296f47f
6 changed files with 190 additions and 129 deletions

View File

@ -27,7 +27,6 @@ import qutebrowser.commands.commands
import qutebrowser.utils.config as config
from qutebrowser.commands.exceptions import (ArgumentCountError,
NoSuchCommandError)
from qutebrowser.utils.completion import CompletionModel
# A mapping from command-strings to command objects.
cmd_dict = {}
@ -170,21 +169,3 @@ class CommandParser(QObject):
else:
raise
self._run(count=count)
class CommandCompletionModel(CompletionModel):
"""A CompletionModel filled with all commands and descriptions."""
# pylint: disable=abstract-method
def __init__(self, parent=None):
super().__init__(parent)
assert cmd_dict
cmdlist = []
for obj in set(cmd_dict.values()):
if not obj.hide:
doc = obj.__doc__.splitlines()[0].strip().rstrip('.')
cmdlist.append([obj.mainname, doc])
self._data['Commands'] = sorted(cmdlist)
self.init_data()

View File

@ -0,0 +1,18 @@
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# 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 <http://www.gnu.org/licenses/>.
"""Various data models."""

View File

@ -0,0 +1,39 @@
"""A CompletionModel filled with all commands and descriptions."""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# 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 <http://www.gnu.org/licenses/>.
from qutebrowser.commands.utils import cmd_dict
from qutebrowser.models.completion import CompletionModel
class CommandCompletionModel(CompletionModel):
"""A CompletionModel filled with all commands and descriptions."""
# pylint: disable=abstract-method
def __init__(self, parent=None):
super().__init__(parent)
assert cmd_dict
cmdlist = []
for obj in set(cmd_dict.values()):
if not obj.hide:
doc = obj.__doc__.splitlines()[0].strip().rstrip('.')
cmdlist.append([obj.mainname, doc])
self._data['Commands'] = sorted(cmdlist)
self.init_data()

View File

@ -1,9 +1,8 @@
"""The base data models for completion in the commandline.
"""The base completion model for completion in the command line.
Contains:
CompletionModel -- A simple tree model based on Python data.
CompletionItem -- One item in the CompletionModel.
CompletionFilterModel -- A QSortFilterProxyModel subclass for completions.
"""
@ -26,8 +25,7 @@ Contains:
from collections import OrderedDict
from PyQt5.QtCore import (QAbstractItemModel, Qt, QModelIndex, QVariant,
QSortFilterProxyModel)
from PyQt5.QtCore import QAbstractItemModel, Qt, QModelIndex, QVariant
class CompletionModel(QAbstractItemModel):
@ -303,107 +301,3 @@ class CompletionItem():
if self.parent:
return self.parent.children.index(self)
return 0
class CompletionFilterModel(QSortFilterProxyModel):
"""Subclass of QSortFilterProxyModel with custom sorting/filtering."""
_pattern = None
srcmodel = None
def __init__(self, parent=None):
super().__init__(parent)
self._pattern = ''
@property
def pattern(self):
"""Getter for pattern."""
return self._pattern
def setsrc(self, model):
"""Set a new source model and clear the pattern.
model -- The new source model.
"""
self.setSourceModel(model)
self.srcmodel = model
self.pattern = ''
@pattern.setter
def pattern(self, val):
"""Setter for pattern.
Invalidates the filter and re-sorts the model.
If the current completion model overrides sort(), it is used.
If not, the default implementation in QCompletionFilterModel is called.
"""
self._pattern = val
self.invalidateFilter()
sortcol = 0
srcmodel = self.sourceModel()
if srcmodel is not None:
try:
srcmodel.sort(sortcol)
except NotImplementedError:
self.sort(sortcol)
self.invalidate()
def filterAcceptsRow(self, row, parent):
"""Custom filter implementation.
Override QSortFilterProxyModel::filterAcceptsRow.
row -- The row of the item.
parent -- The parent item QModelIndex.
Return True if self.pattern is contained in item, or if it's a root
item (category). Else returns False.
"""
if parent == QModelIndex():
return True
idx = self.srcmodel.index(row, 0, parent)
data = self.srcmodel.data(idx).value()
# TODO more sophisticated filtering
if not self.pattern:
return True
return self.pattern in data
def lessThan(self, lindex, rindex):
"""Custom sorting implementation.
lindex -- The QModelIndex of the left item (*left* < right)
rindex -- The QModelIndex of the right item (left < *right*)
Prefers all items which start with self.pattern. Other than that, uses
normal Python string sorting.
"""
left = self.srcmodel.data(lindex).value()
right = self.srcmodel.data(rindex).value()
leftstart = left.startswith(self.pattern)
rightstart = right.startswith(self.pattern)
if leftstart and rightstart:
return left < right
elif leftstart:
return True
elif rightstart:
return False
else:
return left < right
def first_item(self):
"""Return the first item in the model."""
cat = self.index(0, 0)
return self.index(0, 0, cat)
def last_item(self):
"""Return the last item in the model."""
cat = self.index(self.rowCount() - 1, 0)
return self.index(self.rowCount(cat) - 1, 0, cat)

View File

@ -0,0 +1,129 @@
"""A filtering/sorting base model for completions.
Contains:
CompletionFilterModel -- A QSortFilterProxyModel subclass for completions.
"""
# Copyright 2014 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# 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 <http://www.gnu.org/licenses/>.
from PyQt5.QtCore import QModelIndex, QSortFilterProxyModel
class CompletionFilterModel(QSortFilterProxyModel):
"""Subclass of QSortFilterProxyModel with custom sorting/filtering."""
_pattern = None
srcmodel = None
def __init__(self, parent=None):
super().__init__(parent)
self._pattern = ''
@property
def pattern(self):
"""Getter for pattern."""
return self._pattern
def setsrc(self, model):
"""Set a new source model and clear the pattern.
model -- The new source model.
"""
self.setSourceModel(model)
self.srcmodel = model
self.pattern = ''
@pattern.setter
def pattern(self, val):
"""Setter for pattern.
Invalidates the filter and re-sorts the model.
If the current completion model overrides sort(), it is used.
If not, the default implementation in QCompletionFilterModel is called.
"""
self._pattern = val
self.invalidateFilter()
sortcol = 0
srcmodel = self.sourceModel()
if srcmodel is not None:
try:
srcmodel.sort(sortcol)
except NotImplementedError:
self.sort(sortcol)
self.invalidate()
def filterAcceptsRow(self, row, parent):
"""Custom filter implementation.
Override QSortFilterProxyModel::filterAcceptsRow.
row -- The row of the item.
parent -- The parent item QModelIndex.
Return True if self.pattern is contained in item, or if it's a root
item (category). Else returns False.
"""
if parent == QModelIndex():
return True
idx = self.srcmodel.index(row, 0, parent)
data = self.srcmodel.data(idx).value()
# TODO more sophisticated filtering
if not self.pattern:
return True
return self.pattern in data
def lessThan(self, lindex, rindex):
"""Custom sorting implementation.
lindex -- The QModelIndex of the left item (*left* < right)
rindex -- The QModelIndex of the right item (left < *right*)
Prefers all items which start with self.pattern. Other than that, uses
normal Python string sorting.
"""
left = self.srcmodel.data(lindex).value()
right = self.srcmodel.data(rindex).value()
leftstart = left.startswith(self.pattern)
rightstart = right.startswith(self.pattern)
if leftstart and rightstart:
return left < right
elif leftstart:
return True
elif rightstart:
return False
else:
return left < right
def first_item(self):
"""Return the first item in the model."""
cat = self.index(0, 0)
return self.index(0, 0, cat)
def last_item(self):
"""Return the last item in the model."""
cat = self.index(self.rowCount() - 1, 0)
return self.index(self.rowCount(cat) - 1, 0, cat)

View File

@ -32,8 +32,8 @@ from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption,
QTextCursor)
import qutebrowser.utils.config as config
from qutebrowser.utils.completion import CompletionFilterModel
from qutebrowser.commands.utils import CommandCompletionModel
from qutebrowser.models.completionfilter import CompletionFilterModel
from qutebrowser.models.commandcompletion import CommandCompletionModel
class CompletionView(QTreeView):