fix crashes when activating context menu/items while searching

This commit is contained in:
Damien Elmes 2021-01-28 19:10:06 +10:00
parent b148095243
commit 2224fce936

View file

@ -91,6 +91,9 @@ class SidebarModel(QAbstractItemModel):
item.row_in_parent = row item.row_in_parent = row
self._cache_rows(item) self._cache_rows(item)
def item_for_index(self, idx: QModelIndex) -> SidebarItem:
return idx.internalPointer()
# Qt API # Qt API
###################################################################### ######################################################################
@ -157,20 +160,25 @@ class SidebarModel(QAbstractItemModel):
return theme_manager.icon_from_resources(iconRef) return theme_manager.icon_from_resources(iconRef)
def expand_where_necessary( def expand_where_necessary(model: SidebarModel, tree: QTreeView, parent=None) -> None:
model: QAbstractItemModel, tree: QTreeView, parent=None
) -> None:
parent = parent or QModelIndex() parent = parent or QModelIndex()
for row in range(model.rowCount(parent)): for row in range(model.rowCount(parent)):
idx = model.index(row, 0, parent) idx = model.index(row, 0, parent)
if not idx.isValid(): if not idx.isValid():
continue continue
expand_where_necessary(model, tree, idx) expand_where_necessary(model, tree, idx)
item = idx.internalPointer() item = model.item_for_index(idx)
if item.expanded: if item and item.expanded:
tree.setExpanded(idx, True) tree.setExpanded(idx, True)
class FilterModel(QSortFilterProxyModel):
def item_for_index(self, idx: QModelIndex) -> Optional[SidebarItem]:
if not idx.isValid():
return None
return self.mapToSource(idx).internalPointer()
class SidebarSearchBar(QLineEdit): class SidebarSearchBar(QLineEdit):
def __init__(self, sidebar: SidebarTreeView): def __init__(self, sidebar: SidebarTreeView):
QLineEdit.__init__(self, sidebar) QLineEdit.__init__(self, sidebar)
@ -195,7 +203,7 @@ class SidebarTreeView(QTreeView):
self.browser = browser self.browser = browser
self.mw = browser.mw self.mw = browser.mw
self.col = self.mw.col self.col = self.mw.col
self.current_search = False self.current_search: Optional[str] = None
self.setContextMenuPolicy(Qt.CustomContextMenu) self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.onContextMenu) # type: ignore self.customContextMenuRequested.connect(self.onContextMenu) # type: ignore
@ -226,6 +234,9 @@ class SidebarTreeView(QTreeView):
bgcolor = QPalette().window().color().name() bgcolor = QPalette().window().color().name()
self.setStyleSheet("QTreeView { background: '%s'; }" % bgcolor) self.setStyleSheet("QTreeView { background: '%s'; }" % bgcolor)
def model(self) -> Union[FilterModel, SidebarModel]:
return super().model()
def refresh(self) -> None: def refresh(self) -> None:
"Refresh list. No-op if sidebar is not visible." "Refresh list. No-op if sidebar is not visible."
if not self.isVisible(): if not self.isVisible():
@ -248,8 +259,8 @@ class SidebarTreeView(QTreeView):
if not text.strip(): if not text.strip():
self.refresh() self.refresh()
return return
if not isinstance(self.model(), QSortFilterProxyModel): if not isinstance(self.model(), FilterModel):
filter_model = QSortFilterProxyModel(self) filter_model = FilterModel(self)
filter_model.setSourceModel(self.model()) filter_model.setSourceModel(self.model())
filter_model.setFilterCaseSensitivity(False) # type: ignore filter_model.setFilterCaseSensitivity(False) # type: ignore
filter_model.setRecursiveFilteringEnabled(True) filter_model.setRecursiveFilteringEnabled(True)
@ -264,10 +275,14 @@ class SidebarTreeView(QTreeView):
filter_model.setFilterFixedString(text) filter_model.setFilterFixedString(text)
self.expandAll() self.expandAll()
def drawRow(self, painter: QPainter, options: QStyleOptionViewItem, idx: QModelIndex): def drawRow(
if not self.current_search: self, painter: QPainter, options: QStyleOptionViewItem, idx: QModelIndex
):
if self.current_search is None:
return super().drawRow(painter, options, idx) return super().drawRow(painter, options, idx)
if self.current_search.lower() in self.model().mapToSource(idx).internalPointer().name.lower(): if not (item := self.model().item_for_index(idx)):
return super().drawRow(painter, options, idx)
if self.current_search.lower() in item.name.lower():
brush = QBrush(QColor("lightyellow")) brush = QBrush(QColor("lightyellow"))
painter.save() painter.save()
painter.fillRect(options.rect, brush) painter.fillRect(options.rect, brush)
@ -276,8 +291,7 @@ class SidebarTreeView(QTreeView):
def onClickCurrent(self) -> None: def onClickCurrent(self) -> None:
idx = self.currentIndex() idx = self.currentIndex()
if idx.isValid(): if item := self.model().item_for_index(idx):
item: "aqt.browser.SidebarItem" = idx.internalPointer()
if item.onClick: if item.onClick:
item.onClick() item.onClick()
@ -303,8 +317,8 @@ class SidebarTreeView(QTreeView):
self._onExpansionChange(idx, False) self._onExpansionChange(idx, False)
def _onExpansionChange(self, idx: QModelIndex, expanded: bool) -> None: def _onExpansionChange(self, idx: QModelIndex, expanded: bool) -> None:
item: "aqt.browser.SidebarItem" = idx.internalPointer() item = self.model().item_for_index(idx)
if item.expanded != expanded: if item and item.expanded != expanded:
item.expanded = expanded item.expanded = expanded
if item.onExpanded: if item.onExpanded:
item.onExpanded(expanded) item.onExpanded(expanded)
@ -476,7 +490,7 @@ class SidebarTreeView(QTreeView):
def onContextMenu(self, point: QPoint) -> None: def onContextMenu(self, point: QPoint) -> None:
idx: QModelIndex = self.indexAt(point) idx: QModelIndex = self.indexAt(point)
item: "aqt.browser.SidebarItem" = idx.internalPointer() item = self.model().item_for_index(idx)
if not item: if not item:
return return
item_type: SidebarItemType = item.item_type item_type: SidebarItemType = item.item_type