diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index 47696ad8a..084dc3238 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -219,23 +219,26 @@ class DeckManager: self.select(int(list(self.decks.keys())[0])) self.save() - def allNames(self, dyn: bool = True, forceDefault: bool = True) -> List: + def allNames(self, dyn: bool = True, force_default: bool = True) -> List: "An unsorted list of all deck names." if dyn: - return [x["name"] for x in self.all(forceDefault=forceDefault)] + return [x["name"] for x in self.all(force_default=force_default)] else: return [ - x["name"] for x in self.all(forceDefault=forceDefault) if not x["dyn"] + x["name"] for x in self.all(force_default=force_default) if not x["dyn"] ] - def all(self, forceDefault: bool = True) -> List: - "A list of all decks." + def all(self, force_default: bool = True) -> List: + """A list of all decks. + + list contains default deck if either: + * force_default is True + * there are no other deck + * default deck contains a card + * default deck has a child (assumed not to be the case if assume_no_child) + """ decks = list(self.decks.values()) - if ( - not forceDefault - and not self.col.db.scalar("select 1 from cards where did = 1 limit 1") - and len(decks) > 1 - ): + if not force_default and not self.should_default_be_displayed(force_default): decks = [deck for deck in decks if deck["id"] != 1] return decks @@ -513,6 +516,42 @@ class DeckManager: self._recoverOrphans() self._checkDeckTree() + def should_deck_be_displayed( + self, deck, force_default: bool = True, assume_no_child: bool = False + ) -> bool: + """Whether the deck should appear in main window, browser side list, filter, deck selection... + + True, except for empty default deck without children""" + if deck["id"] != "1": + return True + return self.should_default_be_displayed(force_default, assume_no_child) + + def should_default_be_displayed( + self, + force_default: bool = True, + assume_no_child: bool = False, + default_deck=None, + ) -> bool: + """Whether the default deck should appear in main window, browser side list, filter, deck selection... + + True, except for empty default deck (without children)""" + if force_default: + return True + if self.col.db.scalar("select 1 from cards where did = 1 limit 1"): + return True + if len(self.decks) == 1: + return True + # looking for children + if assume_no_child: + return False + if default_deck is None: + default_deck = self.get(1) + defaultName = default_deck["name"] + for name in self.allNames(): + if name.startswith(f"{defaultName}::"): + return True + return False + # Deck selection ############################################################# diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index 87d912324..a46388eed 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -1156,6 +1156,15 @@ by clicking on one on the left.""" def fillGroups(root, grps, head=""): for g in grps: + baseName = g[0] + did = g[1] + children = g[5] + if str(did) == "1" and not children: + if not self.mw.col.decks.should_default_be_displayed( + force_default=False, assume_no_child=True + ): + + continue item = SidebarItem( g[0], ":/icons/deck.svg", @@ -1312,7 +1321,10 @@ by clicking on one on the left.""" subm.addSeparator() addDecks(subm, children) else: - parent.addItem(shortname, self._filterFunc("deck", name)) + if did != 1 or self.col.decks.should_default_be_displayed( + force_default=False, assume_no_child=True + ): + parent.addItem(shortname, self._filterFunc("deck", name)) # fixme: could rewrite to avoid calculating due # in the future alldecks = self.col.sched.deckDueTree() diff --git a/qt/aqt/studydeck.py b/qt/aqt/studydeck.py index 8a331f5e6..1a024b7c4 100644 --- a/qt/aqt/studydeck.py +++ b/qt/aqt/studydeck.py @@ -51,7 +51,7 @@ class StudyDeck(QDialog): if title: self.setWindowTitle(title) if not names: - names = sorted(self.mw.col.decks.allNames(dyn=dyn, forceDefault=False)) + names = sorted(self.mw.col.decks.allNames(dyn=dyn, force_default=False)) self.nameFunc = None self.origNames = names else: