コード例 #1
0
ファイル: deckbrowser.py プロジェクト: ThoreBor/anki
 def _linkHandler(self, url: str) -> Any:
     if ":" in url:
         (cmd, arg) = url.split(":", 1)
     else:
         cmd = url
     if cmd == "open":
         self.set_current_deck(DeckId(int(arg)))
     elif cmd == "opts":
         self._showOptions(arg)
     elif cmd == "shared":
         self._onShared()
     elif cmd == "import":
         self.mw.onImport()
     elif cmd == "create":
         self._on_create()
     elif cmd == "drag":
         source, target = arg.split(",")
         self._handle_drag_and_drop(DeckId(int(source)),
                                    DeckId(int(target or 0)))
     elif cmd == "collapse":
         self._collapse(DeckId(int(arg)))
     elif cmd == "v2upgrade":
         self._confirm_upgrade()
     elif cmd == "v2upgradeinfo":
         openLink("https://faqs.ankiweb.net/the-anki-2.1-scheduler.html")
     return False
コード例 #2
0
 def _showOptions(self, did: str) -> None:
     m = QMenu(self.mw)
     a = m.addAction(tr.actions_rename())
     qconnect(a.triggered, lambda b, did=did: self._rename(DeckId(int(did))))
     a = m.addAction(tr.actions_options())
     qconnect(a.triggered, lambda b, did=did: self._options(DeckId(int(did))))
     a = m.addAction(tr.actions_export())
     qconnect(a.triggered, lambda b, did=did: self._export(DeckId(int(did))))
     a = m.addAction(tr.actions_delete())
     qconnect(a.triggered, lambda b, did=did: self._delete(DeckId(int(did))))
     gui_hooks.deck_browser_will_show_options_menu(m, int(did))
     m.exec_(QCursor.pos())
コード例 #3
0
ファイル: tree.py プロジェクト: kaczmarj/anki
    def _handle_drag_drop_decks(self, sources: list[SidebarItem],
                                target: SidebarItem) -> bool:
        deck_ids = [
            DeckId(source.id) for source in sources
            if source.item_type == SidebarItemType.DECK
        ]
        if not deck_ids:
            return False

        new_parent = DeckId(target.id)

        reparent_decks(parent=self.browser,
                       deck_ids=deck_ids,
                       new_parent=new_parent).run_in_background()

        return True
コード例 #4
0
ファイル: tree.py プロジェクト: kaczmarj/anki
    def _on_rename_with_parents(self, item: SidebarItem) -> None:
        title = "Anki"
        if item.item_type is SidebarItemType.TAG:
            title = tr.actions_rename_tag()
        elif item.item_type is SidebarItemType.DECK:
            title = tr.actions_rename_deck()

        new_name = getOnlyText(tr.actions_new_name(),
                               title=title,
                               default=item.full_name).replace('"', "")
        if not new_name or new_name == item.full_name:
            return

        if item.item_type is SidebarItemType.TAG:

            def success(out: OpChangesWithCount) -> None:
                if out.count:
                    tooltip(tr.browsing_notes_updated(count=out.count),
                            parent=self)
                else:
                    showInfo(tr.browsing_tag_rename_warning_empty(),
                             parent=self)

            rename_tag(
                parent=self,
                current_name=item.full_name,
                new_name=new_name,
            ).success(success).run_in_background()

        elif item.item_type is SidebarItemType.DECK:
            rename_deck(
                parent=self,
                deck_id=DeckId(item.id),
                new_name=new_name,
            ).run_in_background()
コード例 #5
0
    def __init__(
        self,
        mw: AnkiQt,
        deck_id: DeckId = DeckId(0),
        search: str | None = None,
        search_2: str | None = None,
    ) -> None:
        """If 'deck_id' is non-zero, load and modify its settings.
        Otherwise, build a new deck and derive settings from the current deck.

        If search or search_2 are provided, they will be used as the default
        search text.
        """

        QDialog.__init__(self, mw)
        self.mw = mw
        self.col = self.mw.col
        self._desired_search_1 = search
        self._desired_search_2 = search_2

        self._initial_dialog_setup()

        # set on successful query
        self.deck: FilteredDeckForUpdate

        QueryOp(
            parent=self.mw,
            op=lambda col: col.sched.get_or_create_filtered_deck(deck_id=
                                                                 deck_id),
            success=self.load_deck_and_show,
        ).failure(self.on_fetch_error).run_in_background()
コード例 #6
0
    def rename_deck(self, item: SidebarItem, new_name: str) -> None:
        if not new_name:
            return

        # update UI immediately, to avoid redraw
        item.name = new_name

        full_name = item.name_prefix + new_name
        deck_id = DeckId(item.id)

        def after_fetch(deck: Deck) -> None:
            if full_name == deck.name:
                return

            rename_deck(
                parent=self,
                deck_id=deck_id,
                new_name=full_name,
            ).run_in_background()

        QueryOp(
            parent=self.browser,
            op=lambda col: col.get_deck(deck_id),
            success=after_fetch,
        ).run_in_background()
コード例 #7
0
ファイル: tree.py プロジェクト: kaczmarj/anki
 def toggle_expand(node: DeckTreeNode) -> Callable[[bool], None]:
     return lambda expanded: set_deck_collapsed(
         parent=self,
         deck_id=DeckId(node.deck_id),
         collapsed=not expanded,
         scope=DeckCollapseScope.BROWSER,
     ).run_in_background(initiator=self, )
コード例 #8
0
ファイル: v1.py プロジェクト: RumovZ/anki
 def _checkLeech(self, card: Card, conf: QueueConfig) -> bool:
     "Leech handler. True if card was a leech."
     lf = conf["leechFails"]
     if not lf:
         return False
     # if over threshold or every half threshold reps after that
     if card.lapses >= lf and (card.lapses - lf) % (max(lf // 2, 1)) == 0:
         # add a leech tag
         f = card.note()
         f.add_tag("leech")
         f.flush()
         # handle
         a = conf["leechAction"]
         if a == LEECH_SUSPEND:
             # if it has an old due, remove it from cram/relearning
             if card.odue:
                 card.due = card.odue
             if card.odid:
                 card.did = card.odid
             card.odue = 0
             card.odid = DeckId(0)
             card.queue = QUEUE_TYPE_SUSPENDED
         # notify UI
         hooks.card_did_leech(card)
         return True
     else:
         return False
コード例 #9
0
ファイル: studydeck.py プロジェクト: v-limc/anki
        def success(out: OpChangesWithId) -> None:
            deck = self.mw.col.decks.get(DeckId(out.id))
            self.name = deck["name"]

            # make sure we clean up reset hook when manually exiting
            gui_hooks.state_did_reset.remove(self.onReset)

            QDialog.accept(self)
コード例 #10
0
    def __init__(
        self,
        mw: AnkiQt,
        widget: QWidget,
        label: bool = True,
        starting_deck_id: Optional[DeckId] = None,
    ) -> None:
        QHBoxLayout.__init__(self)
        self._widget = widget  # type: ignore
        self.mw = mw
        self._setup_ui(show_label=label)

        self._selected_deck_id = DeckId(0)
        # default to current deck if starting id not provided
        if starting_deck_id is None:
            starting_deck_id = DeckId(self.mw.col.get_config("curDeck", default=1) or 1)
        self.selected_deck_id = starting_deck_id
コード例 #11
0
 def __init__(self, col: anki.collection.Collection) -> None:
     super().__init__(col)
     self.queueLimit = 50
     self.reportLimit = 1000
     self.dynReportLimit = 99999
     self.reps = 0
     self._haveQueues = False
     self._lrnCutoff = 0
     self._active_decks: List[DeckId] = []
     self._current_deck_id = DeckId(1)
コード例 #12
0
ファイル: deckchooser.py プロジェクト: glutanimate/anki
    def __init__(
        self,
        mw: AnkiQt,
        widget: QWidget,
        label: bool = True,
        starting_deck_id: DeckId | None = None,
        on_deck_changed: Callable[[int], None] | None = None,
    ) -> None:
        QHBoxLayout.__init__(self)
        self._widget = widget  # type: ignore
        self.mw = mw
        self._setup_ui(show_label=label)

        self._selected_deck_id = DeckId(0)
        # default to current deck if starting id not provided
        if starting_deck_id is None:
            starting_deck_id = DeckId(self.mw.col.get_config("curDeck", default=1) or 1)
        self.selected_deck_id = starting_deck_id
        self.on_deck_changed = on_deck_changed
        gui_hooks.operation_did_execute.append(self.on_operation_did_execute)
コード例 #13
0
def display_options_for_deck(deck: DeckDict) -> None:
    if not deck["dyn"]:
        if KeyboardModifiersPressed().shift or aqt.mw.col.schedVer() == 1:
            deck_legacy = aqt.mw.col.decks.get(DeckId(deck["id"]))
            aqt.deckconf.DeckConf(aqt.mw, deck_legacy)
        else:
            DeckOptionsDialog(aqt.mw, deck)
    else:
        aqt.dialogs.open("FilteredDeckConfigDialog",
                         aqt.mw,
                         deck_id=deck["id"])
コード例 #14
0
def create_filtered_deck(search_string) -> int:
    search_term = FilteredDeckConfig.SearchTerm(
        search=search_string,
        limit=100,
        order=0,  # random?
    )

    filtered_deck = get_scheduler().get_or_create_filtered_deck(DeckId(0))
    del filtered_deck.config.search_terms[:]
    filtered_deck.config.search_terms.append(search_term)
    return get_scheduler().add_or_update_filtered_deck(filtered_deck).id
コード例 #15
0
ファイル: tree.py プロジェクト: kaczmarj/anki
    def rename_deck(self, item: SidebarItem, new_name: str) -> None:
        if not new_name or new_name == item.name:
            return

        # update UI immediately, to avoid redraw
        item.name = new_name

        rename_deck(
            parent=self,
            deck_id=DeckId(item.id),
            new_name=item.name_prefix + new_name,
        ).run_in_background()
コード例 #16
0
ファイル: addcards.py プロジェクト: qwcbw/anki
 def setup_choosers(self) -> None:
     defaults = self.col.defaults_for_adding(
         current_review_card=self.mw.reviewer.card)
     self.notetype_chooser = NotetypeChooser(
         mw=self.mw,
         widget=self.form.modelArea,
         starting_notetype_id=NotetypeId(defaults.notetype_id),
         on_button_activated=self.show_notetype_selector,
         on_notetype_changed=self.on_notetype_change,
     )
     self.deck_chooser = aqt.deckchooser.DeckChooser(
         self.mw,
         self.form.deckArea,
         starting_deck_id=DeckId(defaults.deck_id))
コード例 #17
0
ファイル: v1.py プロジェクト: evandroforks/anki
 def _rescheduleRev(self, card: Card, ease: int) -> None:  # type: ignore[override]
     # update interval
     card.lastIvl = card.ivl
     if self._resched(card):
         self._updateRevIvl(card, ease)
         # then the rest
         card.factor = max(1300, card.factor + [-150, 0, 150][ease - 2])
         card.due = self.today + card.ivl
     else:
         card.due = card.odue
     if card.odid:
         card.did = card.odid
         card.odid = DeckId(0)
         card.odue = 0
コード例 #18
0
def set_up_test_deck_and_test_model_and_two_notes():
    deck_id = create_deck("test_deck")

    model_id = create_model(
        model_name="test_model",
        field_names=["field1", "field2"],
        card_descriptions=[
            CardDescription(name="card_1",
                            front="{{field1}}",
                            back="{{field1}}<br> {{field2}}"),
            CardDescription(name="card_2",
                            front="{{field2}}",
                            back="{{field2}}<br> {{field1}}")
        ],
    )

    note_id = add_note(
        model_name="test_model",
        deck_name="test_deck",
        fields={
            "field1": "note1 field1",
            "field2": "note1 field2"
        },
        tags=["tag1"],
    )

    get_decks().set_current(DeckId(deck_id))

    card_ids = get_collection().find_cards(query=f"nid:{note_id}")

    import delay_siblings

    return Setup(
        delay_siblings=delay_siblings,
        model_id=model_id,
        deck_id=deck_id,
        note_id=note_id,
        card1_id=card_ids[0],
        card2_id=card_ids[1],
    )
コード例 #19
0
ファイル: v1.py プロジェクト: evandroforks/anki
 def _rescheduleAsRev(self, card: Card, conf: QueueConfig, early: bool) -> None:
     lapse = card.type == CARD_TYPE_REV
     if lapse:
         if self._resched(card):
             card.due = max(self.today + 1, card.odue)
         else:
             card.due = card.odue
         card.odue = 0
     else:
         self._rescheduleNew(card, conf, early)
     card.queue = QUEUE_TYPE_REV
     card.type = CARD_TYPE_REV
     # if we were dynamic, graduating means moving back to the old deck
     resched = self._resched(card)
     if card.odid:
         card.did = card.odid
         card.odue = 0
         card.odid = DeckId(0)
         # if rescheduling is off, it needs to be set back to a new card
         if not resched and not lapse:
             card.queue = QUEUE_TYPE_NEW
             card.type = CARD_TYPE_NEW
             card.due = self.col.nextID("pos")
コード例 #20
0
 def _removeFromFiltered(self, card: Card) -> None:
     if card.odid:
         card.did = card.odid
         card.odue = 0
         card.odid = DeckId(0)
コード例 #21
0
ファイル: studydeck.py プロジェクト: glutanimate/anki
 def success(out: OpChangesWithId) -> None:
     deck = self.mw.col.decks.get(DeckId(out.id))
     self.name = deck["name"]
     self.accept_with_callback()
コード例 #22
0
def filtered_deck_created(search_string):
    deck_id = create_filtered_deck(search_string)
    yield deck_id
    get_decks().remove([DeckId(deck_id)])
コード例 #23
0
ファイル: tree.py プロジェクト: kaczmarj/anki
 def _selected_decks(self) -> list[DeckId]:
     return [
         DeckId(item.id) for item in self._selected_items()
         if item.item_type == SidebarItemType.DECK
     ]