More validity checks.

This commit is contained in:
Florian Bruhin 2014-06-22 23:32:49 +02:00
parent bf9e829d4d
commit ef5b16556b
8 changed files with 57 additions and 13 deletions

View File

@ -26,6 +26,7 @@ import qutebrowser.config.configdata as configdata
from qutebrowser.models.basecompletion import BaseCompletionModel
from qutebrowser.commands.utils import cmd_dict
from qutebrowser.utils.log import completion as logger
from qutebrowser.utils.misc import qt_ensure_valid
class SettingSectionCompletionModel(BaseCompletionModel):
@ -85,7 +86,9 @@ class SettingOptionCompletionModel(BaseCompletionModel):
# changed before init
return
val = config.get(section, option, raw=True)
self.setData(item.index(), val, Qt.DisplayRole)
idx = item.index()
qt_ensure_valid(idx)
self.setData(idx, val, Qt.DisplayRole)
class SettingValueCompletionModel(BaseCompletionModel):
@ -122,7 +125,9 @@ class SettingValueCompletionModel(BaseCompletionModel):
value = config.get(section, option, raw=True)
if not value:
value = '""'
self.setData(self.cur_item.index(), value, Qt.DisplayRole)
idx = self.cur_item.index()
qt_ensure_valid(idx)
self.setData(idx, value, Qt.DisplayRole)
class CommandCompletionModel(BaseCompletionModel):

View File

@ -27,6 +27,7 @@ from PyQt5.QtCore import QSortFilterProxyModel, QModelIndex
from qutebrowser.models.basecompletion import Role
from qutebrowser.utils.log import completion as logger
from qutebrowser.utils.misc import qt_ensure_valid
class CompletionFilterModel(QSortFilterProxyModel):
@ -80,6 +81,7 @@ class CompletionFilterModel(QSortFilterProxyModel):
count = 0
for i in range(self.rowCount()):
cat = self.index(i, 0)
qt_ensure_valid(cat)
count += self.rowCount(cat)
return count
@ -87,24 +89,34 @@ class CompletionFilterModel(QSortFilterProxyModel):
"""Return the first item in the model."""
for i in range(self.rowCount()):
cat = self.index(i, 0)
qt_ensure_valid(cat)
if cat.model().hasChildren(cat):
return self.index(0, 0, cat)
index = self.index(0, 0, cat)
qt_ensure_valid(index)
return index
return QModelIndex()
def last_item(self):
"""Return the last item in the model."""
for i in range(self.rowCount() - 1, -1, -1):
cat = self.index(i, 0)
qt_ensure_valid(cat)
if cat.model().hasChildren(cat):
return self.index(self.rowCount(cat) - 1, 0, cat)
index = self.index(self.rowCount(cat) - 1, 0, cat)
qt_ensure_valid(index)
return index
return QModelIndex()
def mark_all_items(self, text):
"""Mark the given text in all visible items."""
for i in range(self.rowCount()):
cat = self.index(i, 0)
qt_ensure_valid(cat)
for k in range(self.rowCount(cat)):
index = self.mapToSource(self.index(k, 0, cat))
index = self.index(k, 0, cat)
qt_ensure_valid(index)
index = self.mapToSource(index)
qt_ensure_valid(index)
self.srcmodel.mark_item(index, text)
def setSourceModel(self, model):
@ -130,6 +142,7 @@ class CompletionFilterModel(QSortFilterProxyModel):
if parent == QModelIndex():
return True
idx = self.srcmodel.index(row, 0, parent)
qt_ensure_valid(idx)
data = self.srcmodel.data(idx)
# TODO more sophisticated filtering
if not self.pattern:
@ -149,6 +162,9 @@ class CompletionFilterModel(QSortFilterProxyModel):
Return:
True if left < right, else False
"""
qt_ensure_valid(lindex)
qt_ensure_valid(rindex)
left_sort = self.srcmodel.data(lindex, role=Role.sort)
right_sort = self.srcmodel.data(rindex, role=Role.sort)

View File

@ -57,11 +57,17 @@ class DownloadModel(QAbstractListModel):
def on_data_changed(self, idx):
"""Update view when DownloadManager data changed."""
model_idx = self.index(idx, 0)
qt_ensure_valid(model_idx)
self.dataChanged.emit(model_idx, model_idx)
def last_index(self):
"""Get the last index in the model."""
return self.index(self.rowCount() - 1)
"""Get the last index in the model.
Return:
A (possibly invalid) QModelIndex.
"""
idx = self.index(self.rowCount() - 1)
return idx
def headerData(self, section, orientation, role):
"""Simple constant header."""

View File

@ -31,6 +31,7 @@ import qutebrowser.commands.utils as cmdutils
from qutebrowser.widgets.completiondelegate import CompletionItemDelegate
from qutebrowser.config.style import set_register_stylesheet
from qutebrowser.utils.completer import Completer
from qutebrowser.utils.misc import qt_ensure_valid
class CompletionView(QTreeView):
@ -163,6 +164,7 @@ class CompletionView(QTreeView):
# No completion running at the moment, ignore keypress
return
idx = self._next_idx(prev)
qt_ensure_valid(idx)
self.selectionModel().setCurrentIndex(
idx, QItemSelectionModel.ClearAndSelect |
QItemSelectionModel.Rows)

View File

@ -31,6 +31,7 @@ from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption,
import qutebrowser.config.config as config
from qutebrowser.models.basecompletion import Role
from qutebrowser.config.style import get_stylesheet
from qutebrowser.utils.misc import qt_ensure_valid
class CompletionItemDelegate(QStyledItemDelegate):
@ -70,6 +71,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
"""Draw the icon of an ItemViewItem."""
icon_rect = self._style.subElementRect(
self._style.SE_ItemViewItemDecoration, self._opt, self._opt.widget)
qt_ensure_valid(icon_rect)
mode = QIcon.Normal
if not self._opt.state & QStyle.State_Enabled:
@ -94,10 +96,12 @@ class CompletionItemDelegate(QStyledItemDelegate):
text_rect_ = self._style.subElementRect(
self._style.SE_ItemViewItemText, self._opt, self._opt.widget)
qt_ensure_valid(text_rect_)
margin = self._style.pixelMetric(QStyle.PM_FocusFrameHMargin,
self._opt, self._opt.widget) + 1
# remove width padding
text_rect = text_rect_.adjusted(margin, 0, -margin, 0)
qt_ensure_valid(text_rect)
# move text upwards a bit
if index.parent().isValid():
text_rect.adjust(0, -1, 0, -1)
@ -211,6 +215,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
o.rect = self._style.subElementRect(
self._style.SE_ItemViewItemFocusRect, self._opt, self._opt.widget)
o.state |= QStyle.State_KeyboardFocusChange | QStyle.State_Item
qt_ensure_valid(o.rect)
if state & QStyle.State_Enabled:
cg = QPalette.Normal
else:
@ -246,6 +251,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
docsize = self._doc.size().toSize()
size = self._style.sizeFromContents(QStyle.CT_ItemViewItem, self._opt,
docsize, self._opt.widget)
qt_ensure_valid(size)
return size + QSize(10, 3)
def paint(self, painter, option, index):

View File

@ -23,6 +23,8 @@ from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QLabel, QSizePolicy
from PyQt5.QtGui import QPainter
from qutebrowser.utils.misc import qt_ensure_valid
class TextBase(QLabel):
@ -76,7 +78,9 @@ class TextBase(QLabel):
def resizeEvent(self, e):
"""Extend QLabel::resizeEvent to update the elided text afterwards."""
super().resizeEvent(e)
self._update_elided_text(e.size().width())
size = e.size()
qt_ensure_valid(size)
self._update_elided_text(size.width())
def paintEvent(self, e):
"""Override QLabel::paintEvent to draw elided text."""
@ -84,6 +88,7 @@ class TextBase(QLabel):
super().paintEvent(e)
else:
painter = QPainter(self)
painter.drawText(0, 0, self.geometry().width(),
self.geometry().height(), self.alignment(),
self._elided_text)
geom = self.geometry()
qt_ensure_valid(geom)
painter.drawText(0, 0, geom.width(), geom.height(),
self.alignment(), self._elided_text)

View File

@ -232,6 +232,7 @@ class TabbedBrowser(TabWidget):
if self.count() > 1:
url = tab.url()
if not url.isEmpty():
qt_ensure_valid(url)
self.url_stack.append(url)
self.removeTab(idx)
tab.shutdown(callback=partial(self._cb_tab_shutdown, tab))

View File

@ -26,6 +26,7 @@ from PyQt5.QtGui import QIcon, QPixmap
import qutebrowser.config.config as config
from qutebrowser.config.style import set_register_stylesheet
from qutebrowser.utils.style import Style
from qutebrowser.utils.misc import qt_ensure_valid
class EmptyTabIcon(QIcon):
@ -141,6 +142,8 @@ class TabBar(QTabBar):
"""
if config.get('tabbar', 'expand'):
height = super().tabSizeHint(index).height()
return QSize(self.width() / self.count(), height)
size = QSize(self.width() / self.count(), height)
else:
return super().tabSizeHint(index)
size = super().tabSizeHint(index)
qt_ensure_valid(size)
return size