def _paint_label(self, painter: QPainter) -> None: painter.setPen(theme_manager.qcolor(colors.SLIGHTLY_GREY_TEXT)) font = painter.font() font.setPixelSize(int(1.2 * self._knob_radius)) painter.setFont(font) painter.drawText(self._current_knob_rectangle(), Qt.AlignmentFlag.AlignCenter, self.label)
def _getWindowColor(self): if theme_manager.night_mode: return theme_manager.qcolor("window-bg") if isMac: # standard palette does not return correct window color on macOS return QColor("#ececec") return self.style().standardPalette().color(QPalette.Window)
def _paint_knob(self, painter: QPainter) -> None: if theme_manager.night_mode: color = QColor(theme_manager.DARK_MODE_BUTTON_BG_MIDPOINT) else: color = theme_manager.qcolor(colors.FRAME_BG) painter.setBrush(QBrush(color)) painter.drawEllipse(self._current_knob_rectangle())
def drawRow(self, painter: QPainter, options: QStyleOptionViewItem, idx: QModelIndex) -> None: if self.current_search and (item := self.model().item_for_index(idx)): if item.is_highlighted(): brush = QBrush(theme_manager.qcolor(colors.SUSPENDED_BG)) painter.save() painter.fillRect(options.rect, brush) painter.restore()
def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex) -> None: if self._model.get_cell(index).is_rtl: option.direction = Qt.RightToLeft if row_color := self._model.get_row(index).color: brush = QBrush(theme_manager.qcolor(row_color)) painter.save() painter.fillRect(option.rect, brush) painter.restore()
def _paint_path(self, painter: QPainter) -> None: painter.setBrush(QBrush(theme_manager.qcolor(colors.FRAME_BG))) rectangle = QRectF( self._margin, self._margin, self.width() - 2 * self._margin, self.height() - 2 * self._margin, ) painter.drawRoundedRect(rectangle, self._path_radius, self._path_radius)
def _paint_knob(self, painter: QPainter) -> None: painter.setBrush(QBrush(theme_manager.qcolor(colors.LINK))) painter.drawEllipse(self._current_knob_rectangle())
def path_color(self) -> QColor: color = self._right_color if self.isChecked() else self._left_color return theme_manager.qcolor(color)
class SidebarTreeView(QTreeView): def __init__(self, browser: aqt.browser.Browser) -> None: super().__init__() self.browser = browser self.mw = browser.mw self.col = self.mw.col self.current_search: Optional[str] = None self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect( self.onContextMenu) # type: ignore self.context_menus: Dict[SidebarItemType, Sequence[Tuple[ str, Callable]]] = { SidebarItemType.DECK: ( (tr(TR.ACTIONS_RENAME), self.rename_deck), (tr(TR.ACTIONS_DELETE), self.delete_deck), ), SidebarItemType.TAG: ( (tr(TR.ACTIONS_RENAME), self.rename_tag), (tr(TR.ACTIONS_DELETE), self.remove_tag), ), SidebarItemType.SAVED_SEARCH: ( (tr(TR.ACTIONS_RENAME), self.rename_saved_search), (tr(TR.ACTIONS_DELETE), self.remove_saved_search), ), SidebarItemType.NOTETYPE: ((tr(TR.ACTIONS_MANAGE), self.manage_notetype), ), SidebarItemType.SAVED_SEARCH_ROOT: ((tr(TR.BROWSING_SIDEBAR_SAVE_CURRENT_SEARCH), self.save_current_search), ), } self.setUniformRowHeights(True) self.setHeaderHidden(True) self.setIndentation(15) # this doesn't play nicely with shift+click to OR items - we may want # to put it behind a 'multi-select' mode # self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) self.setDragDropMode(QAbstractItemView.InternalMove) self.setDragDropOverwriteMode(False) qconnect(self.expanded, self.onExpansion) qconnect(self.collapsed, self.onCollapse) # match window background color bgcolor = QPalette().window().color().name() self.setStyleSheet("QTreeView { background: '%s'; }" % bgcolor) def model(self) -> Union[FilterModel, SidebarModel]: return super().model() def refresh(self) -> None: "Refresh list. No-op if sidebar is not visible." if not self.isVisible(): return def on_done(fut: Future) -> None: root = fut.result() model = SidebarModel(root) # from PyQt5.QtTest import QAbstractItemModelTester # tester = QAbstractItemModelTester(model) self.setModel(model) if self.current_search: self.search_for(self.current_search) else: expand_where_necessary(model, self) self.mw.taskman.run_in_background(self._root_tree, on_done) def search_for(self, text: str) -> None: if not text.strip(): self.current_search = None self.refresh() return if not isinstance(self.model(), FilterModel): filter_model = FilterModel(self) filter_model.setSourceModel(self.model()) filter_model.setFilterCaseSensitivity(False) # type: ignore filter_model.setRecursiveFilteringEnabled(True) self.setModel(filter_model) else: filter_model = self.model() self.current_search = text # Without collapsing first, can be very slow. Surely there's # a better way than this? self.collapseAll() filter_model.setFilterFixedString(text) self.expandAll() def drawRow(self, painter: QPainter, options: QStyleOptionViewItem, idx: QModelIndex) -> None: if self.current_search is None: return super().drawRow(painter, options, idx) 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(theme_manager.qcolor("suspended-bg")) painter.save() painter.fillRect(options.rect, brush) painter.restore() return super().drawRow(painter, options, idx)