def _notetype_tree(self, root: SidebarItem) -> None: icon = ":/icons/notetype.svg" root = self._section_root( root=root, name=TR.BROWSING_SIDEBAR_NOTETYPES, icon=icon, collapse_key=Config.Bool.COLLAPSE_NOTETYPES, type=SidebarItemType.NOTETYPE_ROOT, ) for nt in sorted(self.col.models.all(), key=lambda nt: nt["name"].lower()): item = SidebarItem( nt["name"], icon, self._filter_func(SearchTerm(note=nt["name"])), item_type=SidebarItemType.NOTETYPE, id=nt["id"], ) for c, tmpl in enumerate(nt["tmpls"]): child = SidebarItem( tmpl["name"], icon, self._filter_func(SearchTerm(note=nt["name"]), SearchTerm(template=c)), item_type=SidebarItemType.NOTETYPE_TEMPLATE, full_name=f"{nt['name']}::{tmpl['name']}", ) item.add_child(child) root.add_child(item)
def showDupes(self): self.mw.browser_search( SearchTerm( dupe=SearchTerm.Dupe( notetype_id=self.note.model()["id"], first_field=self.note.fields[0] ) ) )
def showDupes(self) -> None: aqt.dialogs.open( "Browser", self.mw, search=(SearchTerm(dupe=SearchTerm.Dupe( notetype_id=self.note.model()["id"], first_field=self.note.fields[0], )), ), )
def set_default_searches(self, deck_name: str) -> None: self.form.search.setText( self.mw.col.build_search_string( SearchTerm(deck=deck_name), SearchTerm(card_state=SearchTerm.CARD_STATE_DUE), )) self.form.search_2.setText( self.mw.col.build_search_string( SearchTerm(deck=deck_name), SearchTerm(card_state=SearchTerm.CARD_STATE_NEW), ))
def _today_tree(self, root: SidebarItem) -> None: icon = ":/icons/clock.svg" root = self._section_root( root=root, name=TR.BROWSING_TODAY, icon=icon, collapse_key=Config.Bool.COLLAPSE_TODAY, type=SidebarItemType.TODAY_ROOT, ) type = SidebarItemType.TODAY search = self._filter_func root.add_simple( name=TR.BROWSING_SIDEBAR_DUE_TODAY, icon=icon, type=type, on_click=search(SearchTerm(due_on_day=0)), ) root.add_simple( name=TR.BROWSING_ADDED_TODAY, icon=icon, type=type, on_click=search(SearchTerm(added_in_days=1)), ) root.add_simple( name=TR.BROWSING_EDITED_TODAY, icon=icon, type=type, on_click=search(SearchTerm(edited_in_days=1)), ) root.add_simple( name=TR.BROWSING_STUDIED_TODAY, icon=icon, type=type, on_click=search(SearchTerm(rated=SearchTerm.Rated(days=1))), ) root.add_simple( name=TR.BROWSING_AGAIN_TODAY, icon=icon, type=type, on_click=search( SearchTerm(rated=SearchTerm.Rated( days=1, rating=SearchTerm.RATING_AGAIN))), ) root.add_simple( name=TR.BROWSING_SIDEBAR_OVERDUE, icon=icon, type=type, on_click=search( SearchTerm(card_state=SearchTerm.CARD_STATE_DUE), SearchTerm(negated=SearchTerm(due_on_day=0)), ), )
def _card_state_tree(self, root: SidebarItem) -> None: icon = ColoredIcon(path=":/icons/card-state.svg", color=colors.DISABLED) root = self._section_root( root=root, name=TR.BROWSING_SIDEBAR_CARD_STATE, icon=icon, collapse_key=Config.Bool.COLLAPSE_CARD_STATE, type=SidebarItemType.CARD_STATE_ROOT, ) type = SidebarItemType.CARD_STATE search = self._filter_func root.add_simple( TR.ACTIONS_NEW, icon=icon.with_color(colors.NEW_COUNT), type=type, on_click=search(SearchTerm(card_state=SearchTerm.CARD_STATE_NEW)), ) root.add_simple( name=TR.SCHEDULING_LEARNING, icon=icon.with_color(colors.LEARN_COUNT), type=type, on_click=search( SearchTerm(card_state=SearchTerm.CARD_STATE_LEARN)), ) root.add_simple( name=TR.SCHEDULING_REVIEW, icon=icon.with_color(colors.REVIEW_COUNT), type=type, on_click=search( SearchTerm(card_state=SearchTerm.CARD_STATE_REVIEW)), ) root.add_simple( name=TR.BROWSING_SUSPENDED, icon=icon.with_color(colors.SUSPENDED_FG), type=type, on_click=search( SearchTerm(card_state=SearchTerm.CARD_STATE_SUSPENDED)), ) root.add_simple( name=TR.BROWSING_BURIED, icon=icon.with_color(colors.BURIED_FG), type=type, on_click=search( SearchTerm(card_state=SearchTerm.CARD_STATE_BURIED)), )
def _linkHandler(self, url): if url == "study": self.mw.col.startTimebox() self.mw.moveToState("review") if self.mw.state == "overview": tooltip(tr(TR.STUDYING_NO_CARDS_ARE_DUE_YET)) elif url == "anki": print("anki menu") elif url == "opts": self.mw.onDeckConf() elif url == "cram": deck = self.mw.col.decks.current()["name"] self.mw.onCram(self.mw.col.build_search_string(SearchTerm(deck=deck))) elif url == "refresh": self.mw.col.sched.rebuild_filtered_deck(self.mw.col.decks.selected()) self.mw.reset() elif url == "empty": self.mw.col.sched.empty_filtered_deck(self.mw.col.decks.selected()) self.mw.reset() elif url == "decks": self.mw.moveToState("deckBrowser") elif url == "review": openLink(aqt.appShared + "info/%s?v=%s" % (self.sid, self.sidVer)) elif url == "studymore" or url == "customStudy": self.onStudyMore() elif url == "unbury": self.onUnbury() elif url.lower().startswith("http"): openLink(url) return False
def _tag_tree(self, root: SidebarItem) -> None: icon = ":/icons/tag.svg" def render(root: SidebarItem, nodes: Iterable[TagTreeNode], head: str = "") -> None: for node in nodes: def toggle_expand() -> Callable[[bool], None]: full_name = head + node.name # pylint: disable=cell-var-from-loop return lambda expanded: self.mw.col.tags.set_expanded( full_name, expanded) item = SidebarItem( node.name, icon, self._filter_func(SearchTerm(tag=head + node.name)), toggle_expand(), node.expanded, item_type=SidebarItemType.TAG, full_name=head + node.name, ) root.add_child(item) newhead = f"{head + node.name}::" render(item, node.children, newhead) tree = self.col.tags.tree() root = self._section_root( root=root, name=TR.BROWSING_SIDEBAR_TAGS, icon=icon, collapse_key=Config.Bool.COLLAPSE_TAGS, type=SidebarItemType.TAG_ROOT, ) root.on_click = self._filter_func( SearchTerm(negated=SearchTerm(tag="none"))) root.add_simple( name=tr(TR.BROWSING_SIDEBAR_UNTAGGED), icon=icon, type=SidebarItemType.TAG_NONE, on_click=self._filter_func(SearchTerm(tag="none")), ) render(root, tree.children)
def _deck_tree(self, root: SidebarItem) -> None: icon = ":/icons/deck.svg" def render(root: SidebarItem, nodes: Iterable[DeckTreeNode], head: str = "") -> None: for node in nodes: def toggle_expand() -> Callable[[bool], None]: did = node.deck_id # pylint: disable=cell-var-from-loop return lambda _: self.mw.col.decks.collapseBrowser(did) item = SidebarItem( node.name, icon, self._filter_func(SearchTerm(deck=head + node.name)), toggle_expand(), not node.collapsed, item_type=SidebarItemType.DECK, id=node.deck_id, full_name=head + node.name, ) root.add_child(item) newhead = f"{head + node.name}::" render(item, node.children, newhead) tree = self.col.decks.deck_tree() root = self._section_root( root=root, name=TR.BROWSING_SIDEBAR_DECKS, icon=icon, collapse_key=Config.Bool.COLLAPSE_DECKS, type=SidebarItemType.DECK_ROOT, ) root.on_click = self._filter_func(SearchTerm(deck="*")) current = root.add_simple( name=tr(TR.BROWSING_CURRENT_DECK), icon=icon, type=SidebarItemType.DECK, on_click=self._filter_func(SearchTerm(deck="current")), ) current.id = self.mw.col.decks.selected() render(root, tree.children)
def __init__(self, mw, first=False, search="", deck=None): QDialog.__init__(self, mw) self.mw = mw self.deck = deck or self.mw.col.decks.current() self.search = search self.form = aqt.forms.dyndconf.Ui_Dialog() self.form.setupUi(self) if first: label = tr(TR.DECKS_BUILD) else: label = tr(TR.ACTIONS_REBUILD) self.ok = self.form.buttonBox.addButton(label, QDialogButtonBox.AcceptRole) self.mw.checkpoint(tr(TR.ACTIONS_OPTIONS)) disable_help_button(self) self.setWindowModality(Qt.WindowModal) qconnect(self.form.buttonBox.helpRequested, lambda: openHelp(HelpPage.FILTERED_DECK)) self.setWindowTitle( without_unicode_isolation( tr(TR.ACTIONS_OPTIONS_FOR, val=self.deck["name"]))) restoreGeom(self, "dyndeckconf") self.initialSetup() self.loadConf() if search: search = self.mw.col.build_search_string( search, SearchTerm(card_state=SearchTerm.CARD_STATE_DUE)) self.form.search.setText(search) search_2 = self.mw.col.build_search_string( search, SearchTerm(card_state=SearchTerm.CARD_STATE_NEW)) self.form.search_2.setText(search_2) self.form.search.selectAll() if self.mw.col.schedVer() == 1: self.form.secondFilter.setVisible(False) self.show() self.exec_() saveGeom(self, "dyndeckconf")
def _commonly_used_tree(self, root: SidebarItem) -> None: item = SidebarItem( tr(TR.BROWSING_WHOLE_COLLECTION), ":/icons/collection.svg", self._filter_func(), item_type=SidebarItemType.COLLECTION, ) root.addChild(item) item = SidebarItem( tr(TR.BROWSING_CURRENT_DECK), ":/icons/deck.svg", self._filter_func(SearchTerm(deck="current")), item_type=SidebarItemType.CURRENT_DECK, ) root.addChild(item)
def _on_render_latex(self): self.progress_dialog = self.mw.progress.start() try: out = self.mw.col.media.render_all_latex( self._on_render_latex_progress) if self.progress_dialog.wantCancel: return finally: self.mw.progress.finish() self.progress_dialog = None if out is not None: nid, err = out self.mw.browser_search(SearchTerm(nid=nid)) showText(err, type="html") else: tooltip(tr(TR.MEDIA_CHECK_ALL_LATEX_RENDERED))
def onHistory(self) -> None: m = QMenu(self) for nid in self.history: if self.mw.col.findNotes(SearchTerm(nid=nid)): note = self.mw.col.getNote(nid) fields = note.fields txt = htmlToTextLine(", ".join(fields)) if len(txt) > 30: txt = txt[:30] + "..." line = tr(TR.ADDING_EDIT, val=txt) line = gui_hooks.addcards_will_add_history_entry(line, note) a = m.addAction(line) qconnect(a.triggered, lambda b, nid=nid: self.editHistory(nid)) else: a = m.addAction(tr(TR.ADDING_NOTE_DELETED)) a.setEnabled(False) gui_hooks.add_cards_will_show_history_menu(self, m) m.exec_(self.historyButton.mapToGlobal(QPoint(0, 0)))
def render(root: SidebarItem, nodes: Iterable[DeckTreeNode], head: str = "") -> None: for node in nodes: def toggle_expand() -> Callable[[bool], None]: did = node.deck_id # pylint: disable=cell-var-from-loop return lambda _: self.mw.col.decks.collapseBrowser(did) item = SidebarItem( node.name, icon, self._filter_func(SearchTerm(deck=head + node.name)), toggle_expand(), not node.collapsed, item_type=SidebarItemType.DECK, id=node.deck_id, full_name=head + node.name, ) root.add_child(item) newhead = f"{head + node.name}::" render(item, node.children, newhead)
def render(root: SidebarItem, nodes: Iterable[TagTreeNode], head: str = "") -> None: for node in nodes: def toggle_expand() -> Callable[[bool], None]: full_name = head + node.name # pylint: disable=cell-var-from-loop return lambda expanded: self.mw.col.tags.set_expanded( full_name, expanded) item = SidebarItem( node.name, icon, self._filter_func(SearchTerm(tag=head + node.name)), toggle_expand(), node.expanded, item_type=SidebarItemType.TAG, full_name=head + node.name, ) root.add_child(item) newhead = f"{head + node.name}::" render(item, node.children, newhead)
def _flags_tree(self, root: SidebarItem) -> None: icon = ColoredIcon(path=":/icons/flag.svg", color=colors.DISABLED) search = self._filter_func root = self._section_root( root=root, name=TR.BROWSING_SIDEBAR_FLAGS, icon=icon, collapse_key=Config.Bool.COLLAPSE_FLAGS, type=SidebarItemType.FLAG_ROOT, ) root.on_click = search(SearchTerm(flag=SearchTerm.FLAG_ANY)) type = SidebarItemType.FLAG root.add_simple( TR.ACTIONS_RED_FLAG, icon=icon.with_color(colors.FLAG1_FG), type=type, on_click=search(SearchTerm(flag=SearchTerm.FLAG_RED)), ) root.add_simple( TR.ACTIONS_ORANGE_FLAG, icon=icon.with_color(colors.FLAG2_FG), type=type, on_click=search(SearchTerm(flag=SearchTerm.FLAG_ORANGE)), ) root.add_simple( TR.ACTIONS_GREEN_FLAG, icon=icon.with_color(colors.FLAG3_FG), type=type, on_click=search(SearchTerm(flag=SearchTerm.FLAG_GREEN)), ) root.add_simple( TR.ACTIONS_BLUE_FLAG, icon=icon.with_color(colors.FLAG4_FG), type=type, on_click=search(SearchTerm(flag=SearchTerm.FLAG_BLUE)), ) root.add_simple( TR.BROWSING_NO_FLAG, icon=icon.with_color(colors.DISABLED), type=type, on_click=search(SearchTerm(flag=SearchTerm.FLAG_NONE)), )
def editHistory(self, nid): self.mw.browser_search(SearchTerm(nid=nid))
def accept(self) -> None: f = self.form i = self.radioIdx spin = f.spin.value() if i == RADIO_NEW: self.deck["extendNew"] = spin self.mw.col.decks.save(self.deck) self.mw.col.sched.extendLimits(spin, 0) self.mw.reset() QDialog.accept(self) return elif i == RADIO_REV: self.deck["extendRev"] = spin self.mw.col.decks.save(self.deck) self.mw.col.sched.extendLimits(0, spin) self.mw.reset() QDialog.accept(self) return elif i == RADIO_CRAM: tags = self._getTags() # the rest create a filtered deck cur = self.mw.col.decks.byName(tr( TR.CUSTOM_STUDY_CUSTOM_STUDY_SESSION)) if cur: if not cur["dyn"]: showInfo(tr(TR.CUSTOM_STUDY_MUST_RENAME_DECK)) QDialog.accept(self) return else: # safe to empty self.mw.col.sched.empty_filtered_deck(cur["id"]) # reuse; don't delete as it may have children dyn = cur self.mw.col.decks.select(cur["id"]) else: did = self.mw.col.decks.new_filtered( tr(TR.CUSTOM_STUDY_CUSTOM_STUDY_SESSION)) dyn = self.mw.col.decks.get(did) # and then set various options if i == RADIO_FORGOT: search = self.mw.col.build_search_string( SearchTerm(rated=SearchTerm.Rated( days=spin, rating=SearchTerm.RATING_AGAIN))) dyn["terms"][0] = [search, DYN_MAX_SIZE, DYN_RANDOM] dyn["resched"] = False elif i == RADIO_AHEAD: search = self.mw.col.build_search_string( SearchTerm(due_in_days=spin)) dyn["terms"][0] = [search, DYN_MAX_SIZE, DYN_DUE] dyn["resched"] = True elif i == RADIO_PREVIEW: search = self.mw.col.build_search_string( SearchTerm(card_state=SearchTerm.CARD_STATE_NEW), SearchTerm(added_in_days=spin), ) dyn["terms"][0] = [search, DYN_MAX_SIZE, DYN_OLDEST] dyn["resched"] = False elif i == RADIO_CRAM: type = f.cardType.currentRow() if type == TYPE_NEW: terms = self.mw.col.build_search_string( SearchTerm(card_state=SearchTerm.CARD_STATE_NEW)) ord = DYN_ADDED dyn["resched"] = True elif type == TYPE_DUE: terms = self.mw.col.build_search_string( SearchTerm(card_state=SearchTerm.CARD_STATE_DUE)) ord = DYN_DUE dyn["resched"] = True elif type == TYPE_REVIEW: terms = self.mw.col.build_search_string( SearchTerm(card_state=SearchTerm.CARD_STATE_NEW), negate=True) ord = DYN_RANDOM dyn["resched"] = True else: terms = "" ord = DYN_RANDOM dyn["resched"] = False dyn["terms"][0] = [(terms + tags).strip(), spin, ord] # add deck limit dyn["terms"][0][0] = self.mw.col.build_search_string( dyn["terms"][0][0], SearchTerm(deck=self.deck["name"])) self.mw.col.decks.save(dyn) # generate cards self.created_custom_study = True if not self.mw.col.sched.rebuild_filtered_deck(dyn["id"]): showWarning(tr(TR.CUSTOM_STUDY_NO_CARDS_MATCHED_THE_CRITERIA_YOU)) return self.mw.moveToState("overview") QDialog.accept(self)
def editHistory(self, nid) -> None: aqt.dialogs.open("Browser", self.mw, search=(SearchTerm(nid=nid), ))