More validity checks.
This commit is contained in:
parent
bf9e829d4d
commit
ef5b16556b
@ -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):
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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."""
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user