class LogFilter(QFrame): def __init__(self, parent=None): super(LogFilter, self).__init__(parent=parent) setup_ui(self) self.filter_model = FilterModel(parent=self) self._viewer = None self.revs_menu = QMenu(parent=self) self.revs_separator = None self.rev_actions = QActionGroup(self) self.rev_actions.addAction(self.action_all_refs) self.select_revs_button.setMenu(self.revs_menu) self.action_all_refs.revs = None self.action_all_refs.triggered.connect(self.show_all_refs) self.action_select_branches.triggered.connect(self.pick_branches) self.filter_text.textEdited.connect(self.filter_text_edited) @property def source_model(self): return self.filter_model.sourceModel() @source_model.setter def source_model(self, model): self.filter_model.setSourceModel(model) self.revs_menu.clear() for action in self.rev_actions.actions(): if action is not self.action_all_refs: self.rev_actions.removeAction(action) self.revs_menu.addAction(self.action_all_refs) if not model.repo.head_ref: self.revs_menu.addAction(self.create_rev_action(model.repo, 'HEAD')) for branch in model.repo.branches: self.revs_menu.addAction(self.create_rev_action(model.repo, branch)) if model.all: self._select_action(self.action_all_refs) else: selected_revs = model.revs if not selected_revs: if model.repo.head_ref: selected_revs = (model.repo.head_ref,) else: selected_revs = ('HEAD',) action = self._find_rev_action(selected_revs) if not action: action = self.create_rev_action(model.repo, model.revs) self.revs_menu.addAction(action) self._select_action(action) self.revs_separator = self.revs_menu.addSeparator() self.revs_menu.addAction(self.action_select_branches) @property def viewer(self): return self._viewer @viewer.setter def viewer(self, new_viewer): self._viewer = new_viewer self._viewer.setModel(self.filter_model) def create_rev_action(self, repo, *revs): action = QAction(self.revs_menu) action.revs = revs action.setText(', '.join(str(rev) for rev in revs)) action.setCheckable(True) action.setActionGroup(self.rev_actions) action.triggered.connect(self._revs_action_triggered) return action def show_all_refs(self): self._select_action(self.action_all_refs) with busy_cursor(): self.source_model.revs = () self.source_model.all = True self.source_model.refresh() def pick_branches(self): dialog = PickBranchesDialog(repo=self.source_model.repo, parent=self) if dialog.exec_() == dialog.Accepted: self.show_revs(*dialog.selected_branches) def _select_action(self, action): action.setChecked(True) self.select_revs_button.setText(action.text()) def _revs_action_triggered(self): self._select_action(self.sender()) with busy_cursor(): self.source_model.revs = self.sender().revs self.source_model.all = False self.source_model.refresh() def _find_rev_action(self, revs): return next((action for action in self.rev_actions.actions() if action.revs == revs), None) def show_revs(self, *revs): action = self._find_rev_action(revs) if not action: action = self.create_rev_action(self.source_model.repo, *revs) self.revs_menu.insertAction(self.revs_separator, action) self._select_action(action) with busy_cursor(): self.source_model.revs = revs self.source_model.all = False self.source_model.refresh() def filter_text_edited(self, text): if text: self.viewer.hideColumn(0) self.filter_model.filters += self.filter_graph_row else: self.filter_model.filters -= self.filter_graph_row self.viewer.showColumn(0) def filter_graph_row(self, graph_row): return commit_matches_text(graph_row.log_entry, self.filter_text.text())