Ejemplo n.º 1
0
 def __init__(self, dlg: QDialog) -> None:
     QDialog.__init__(self, dlg)
     self.addonsDlg = dlg
     self.mgr = dlg.mgr
     self.mw = self.mgr.mw
     self.ids: List[int] = []
     self.form = aqt.forms.getaddons.Ui_Dialog()
     self.form.setupUi(self)
     b = self.form.buttonBox.addButton(
         tr(TR.ADDONS_BROWSE_ADDONS), QDialogButtonBox.ActionRole
     )
     qconnect(b.clicked, self.onBrowse)
     disable_help_button(self)
     restoreGeom(self, "getaddons", adjustSize=True)
     self.exec_()
     saveGeom(self, "getaddons")
Ejemplo n.º 2
0
 def loadAddons(self) -> None:
     for addon in self.all_addon_meta():
         if not addon.enabled:
             continue
         if not addon.compatible():
             continue
         self.dirty = True
         try:
             __import__(addon.dir_name)
         except:
             showWarning(
                 tr(
                     TR.ADDONS_FAILED_TO_LOAD,
                     name=addon.human_name(),
                     traceback=traceback.format_exc(),
                 ))
Ejemplo n.º 3
0
    def addGroup(self) -> None:
        name = getOnlyText(tr(TR.SCHEDULING_NEW_OPTIONS_GROUP_NAME))
        if not name:
            return

        # first, save currently entered data to current conf
        self.saveConf()
        # then clone the conf
        id = self.mw.col.decks.add_config_returning_id(name,
                                                       clone_from=self.conf)
        gui_hooks.deck_conf_did_add_config(self, self.deck, self.conf, name,
                                           id)
        # set the deck to the new conf
        self.deck["conf"] = id
        # then reload the conf list
        self.loadConfs()
Ejemplo n.º 4
0
        def but(i: int, label: str) -> str:
            if i == default:
                extra = """id="defease" class="focus" """
            else:
                extra = ""
            due = self._buttonTime(i)
            return """
<td align=center>%s<button %s title="%s" data-ease="%s" onclick='pycmd("ease%d");'>\
%s</button></td>""" % (
                due,
                extra,
                tr(TR.ACTIONS_SHORTCUT_KEY, val=i),
                i,
                i,
                label,
            )
Ejemplo n.º 5
0
    def onRename(self) -> None:
        idx = self.currentIdx
        f = self.model["flds"][idx]
        name = self._uniqueName(tr(TR.ACTIONS_NEW_NAME), self.currentIdx,
                                f["name"])
        if not name:
            return

        old_name = f["name"]
        self.change_tracker.mark_basic()
        self.mm.rename_field(self.model, f, name)
        gui_hooks.fields_did_rename_field(self, f, old_name)

        self.saveField()
        self.fillFields()
        self.form.fieldList.setCurrentRow(idx)
Ejemplo n.º 6
0
 def __init__(self, dlg) -> None:
     QDialog.__init__(self, dlg)
     self.addonsDlg = dlg
     self.mgr = dlg.mgr
     self.mw = self.mgr.mw
     self.ids: List[int] = []
     self.form = aqt.forms.getaddons.Ui_Dialog()
     self.form.setupUi(self)
     b = self.form.buttonBox.addButton(tr(TR.ADDONS_BROWSE_ADDONS),
                                       QDialogButtonBox.ActionRole)
     qconnect(b.clicked, self.onBrowse)
     self.setWindowFlags(self.windowFlags()
                         & ~Qt.WindowContextHelpButtonHint)  # type: ignore
     restoreGeom(self, "getaddons", adjustSize=True)
     self.exec_()
     saveGeom(self, "getaddons")
Ejemplo n.º 7
0
def setupApkgImport(mw: AnkiQt, importer: AnkiPackageImporter) -> bool:
    base = os.path.basename(importer.file).lower()
    full = ((base == "collection.apkg") or re.match("backup-.*\\.apkg", base)
            or base.endswith(".colpkg"))
    if not full:
        # adding
        return True
    if not mw.restoringBackup and not askUser(
            tr(TR.IMPORTING_THIS_WILL_DELETE_YOUR_EXISTING_COLLECTION),
            msgfunc=QMessageBox.warning,
            defaultno=True,
    ):
        return False

    replaceWithApkg(mw, importer.file, mw.restoringBackup)
    return False
Ejemplo n.º 8
0
Archivo: sound.py Proyecto: st2025/anki
 def postprocess(self, encode=True) -> None:
     self.encode = encode
     for c in processingChain:
         # print c
         if not self.encode and c[0] == "lame":
             continue
         try:
             cmd, env = _packagedCmd(c)
             ret = retryWait(
                 subprocess.Popen(cmd, startupinfo=startup_info(), env=env))
         except:
             ret = True
         finally:
             self.cleanup()
         if ret:
             raise Exception(tr(TR.MEDIA_ERROR_RUNNING, val=" ").join(cmd))
Ejemplo n.º 9
0
    def _remove_tag(self, item: "aqt.browser.SidebarItem") -> None:
        old_name = item.full_name

        def do_remove():
            self.mw.col.backend.clear_tag(old_name)
            self.col.tags.rename_tag(old_name, "")

        def on_done(fut: Future):
            self.mw.requireReset(reason=ResetReason.BrowserRemoveTags, context=self)
            self.browser.model.endReset()
            fut.result()
            self.browser.maybeRefreshSidebar()

        self.mw.checkpoint(tr(TR.ACTIONS_REMOVE_TAG))
        self.browser.model.beginReset()
        self.mw.taskman.run_in_background(do_remove, on_done)
Ejemplo n.º 10
0
 def _desc(self, deck: Dict[str, Any]) -> str:
     if deck["dyn"]:
         desc = tr(TR.STUDYING_THIS_IS_A_SPECIAL_DECK_FOR)
         desc += f" {tr(TR.STUDYING_CARDS_WILL_BE_AUTOMATICALLY_RETURNED_TO)}"
         desc += f" {tr(TR.STUDYING_DELETING_THIS_DECK_FROM_THE_DECK)}"
     else:
         desc = deck.get("desc", "")
         if deck.get("md", False):
             desc = self.mw.col.render_markdown(desc)
     if not desc:
         return "<p>"
     if deck["dyn"]:
         dyn = "dyn"
     else:
         dyn = ""
     return f'<div class="descfont descmid description {dyn}">{desc}</div>'
Ejemplo n.º 11
0
    def _delete_deck(self, item: SidebarItem) -> None:
        did = item.id
        if self.mw.deckBrowser.ask_delete_deck(did):

            def do_delete() -> None:
                return self.mw.col.decks.rem(did, True)

            def on_done(fut: Future) -> None:
                self.mw.requireReset(reason=ResetReason.BrowserDeleteDeck, context=self)
                self.browser.search()
                self.browser.model.endReset()
                self.refresh()
                res = fut.result()  # Required to check for errors

            self.mw.checkpoint(tr(TR.DECKS_DELETE_DECK))
            self.browser.model.beginReset()
            self.mw.taskman.run_in_background(do_delete, on_done)
Ejemplo n.º 12
0
def prompt_to_update(
    parent: QWidget,
    mgr: AddonManager,
    client: HttpClient,
    ids: List[int],
    on_done: Callable[[List[DownloadLogEntry]], None],
) -> None:
    names = map(lambda x: mgr.addonName(str(x)), ids)
    if not askUser(
        tr(TR.ADDONS_THE_FOLLOWING_ADDONS_HAVE_UPDATES_AVAILABLE)
        + "\n\n"
        + "\n".join(names)
    ):
        # on_done is not called if the user cancels
        return

    download_addons(parent, mgr, ids, on_done, client)
Ejemplo n.º 13
0
    def _renderDeckTree(self, top: DeckTreeNode) -> str:
        buf = """
<tr><th colspan=5 align=start>%s</th><th class=count>%s</th>
<th class=count>%s</th><th class=optscol></th></tr>""" % (
            _("Deck"),
            tr(TR.STATISTICS_DUE_COUNT),
            _("New"),
        )
        buf += self._topLevelDragRow()

        ctx = RenderDeckNodeContext(
            current_deck_id=self.mw.col.conf["curDeck"])

        for child in top.children:
            buf += self._render_deck_node(child, ctx)

        return buf
Ejemplo n.º 14
0
    def onAddMedia(self) -> None:
        extension_filter = " ".join(
            f"*.{extension}"
            for extension in sorted(itertools.chain(pics, audio)))
        filter = f"{tr(TR.EDITING_MEDIA)} ({extension_filter})"

        def accept(file: str) -> None:
            self.addMedia(file)

        file = getFile(
            parent=self.widget,
            title=tr(TR.EDITING_ADD_MEDIA),
            cb=cast(Callable[[Any], None], accept),
            filter=filter,
            key="media",
        )
        self.parentWindow.activateWindow()
Ejemplo n.º 15
0
    def _remove_tags(self, _item: SidebarItem) -> None:
        tags = self._selected_tags()

        def do_remove() -> int:
            return self.col._backend.expunge_tags(" ".join(tags))

        def on_done(fut: Future) -> None:
            self.mw.requireReset(reason=ResetReason.BrowserRemoveTags,
                                 context=self)
            self.browser.model.endReset()
            tooltip(tr(TR.BROWSING_NOTES_UPDATED, count=fut.result()),
                    parent=self)
            self.refresh()

        self.mw.checkpoint(tr(TR.ACTIONS_REMOVE_TAG))
        self.browser.model.beginReset()
        self.mw.taskman.with_progress(do_remove, on_done)
Ejemplo n.º 16
0
    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))
Ejemplo n.º 17
0
 def _answerButtonList(self) -> Tuple[Tuple[int, str], ...]:
     button_count = self.mw.col.sched.answerButtons(self.card)
     if button_count == 2:
         buttons_tuple: Tuple[Tuple[int, str], ...] = (
             (1, tr(TR.STUDYING_AGAIN)),
             (2, tr(TR.STUDYING_GOOD)),
         )
     elif button_count == 3:
         buttons_tuple = (
             (1, tr(TR.STUDYING_AGAIN)),
             (2, tr(TR.STUDYING_GOOD)),
             (3, tr(TR.STUDYING_EASY)),
         )
     else:
         buttons_tuple = (
             (1, tr(TR.STUDYING_AGAIN)),
             (2, tr(TR.STUDYING_HARD)),
             (3, tr(TR.STUDYING_GOOD)),
             (4, tr(TR.STUDYING_EASY)),
         )
     buttons_tuple = gui_hooks.reviewer_will_init_answer_buttons(
         buttons_tuple, self, self.card)
     return buttons_tuple
Ejemplo n.º 18
0
    def update_global(self) -> None:
        restart_required = False

        self.update_video_driver()

        newScale = self.form.uiScale.value() / 100
        if newScale != self.mw.pm.uiScale():
            self.mw.pm.setUiScale(newScale)
            restart_required = True

        if self.mw.pm.night_mode() != self.form.nightMode.isChecked():
            self.mw.pm.set_night_mode(not self.mw.pm.night_mode())
            restart_required = True

        if restart_required:
            showInfo(tr(TR.PREFERENCES_CHANGES_WILL_TAKE_EFFECT_WHEN_YOU))

        self.updateOptions()
Ejemplo n.º 19
0
 def add_simple(
     self,
     name: Union[str, TR],
     icon: Union[str, ColoredIcon],
     type: SidebarItemType,
     search_node: Optional[SearchNode],
 ) -> SidebarItem:
     "Add child sidebar item, and return it."
     if not isinstance(name, str):
         name = tr(name)
     item = SidebarItem(
         name=name,
         icon=icon,
         search_node=search_node,
         item_type=type,
     )
     self.add_child(item)
     return item
Ejemplo n.º 20
0
    def onConfig(self) -> None:
        addon = self.onlyOneSelected()
        if not addon:
            return

        # does add-on manage its own config?
        act = self.mgr.configAction(addon)
        if act:
            ret = act()
            if ret is not False:
                return

        conf = self.mgr.getConfig(addon)
        if conf is None:
            showInfo(tr(TR.ADDONS_ADDON_HAS_NO_CONFIGURATION))
            return

        ConfigEditor(self, addon, conf)
Ejemplo n.º 21
0
 def rename_saved_search(self, item: SidebarItem, new_name: str) -> None:
     old_name = item.name
     conf = self._get_saved_searches()
     try:
         filt = conf[old_name]
     except KeyError:
         return
     if new_name in conf and not askUser(
         tr(TR.BROWSING_CONFIRM_SAVED_SEARCH_OVERWRITE, name=new_name)
     ):
         return
     conf[new_name] = filt
     del conf[old_name]
     self._set_saved_searches(conf)
     self.refresh(
         lambda item: item.item_type == SidebarItemType.SAVED_SEARCH
         and item.name == new_name
     )
Ejemplo n.º 22
0
 def __init__(self, mw: aqt.AnkiQt) -> None:
     QDialog.__init__(self, None, Qt.Window)
     mw.garbage_collect_on_dialog_finish(self)
     self.mw = mw
     self.form = aqt.forms.editcurrent.Ui_Dialog()
     self.form.setupUi(self)
     self.setWindowTitle(tr(TR.EDITING_EDIT_CURRENT))
     disable_help_button(self)
     self.setMinimumHeight(400)
     self.setMinimumWidth(250)
     self.form.buttonBox.button(QDialogButtonBox.Close).setShortcut(
         QKeySequence("Ctrl+Return"))
     self.editor = aqt.editor.Editor(self.mw, self.form.fieldsArea, self)
     self.editor.card = self.mw.reviewer.card
     self.editor.set_note(self.mw.reviewer.card.note(), focusTo=0)
     restoreGeom(self, "editcurrent")
     gui_hooks.operation_did_execute.append(self.on_operation_did_execute)
     self.show()
Ejemplo n.º 23
0
 def add_simple(
     self,
     name: Union[str, TR.V],
     icon: Union[str, ColoredIcon],
     type: SidebarItemType,
     on_click: Callable[[], None],
 ) -> SidebarItem:
     "Add child sidebar item, and return it."
     if not isinstance(name, str):
         name = tr(name)
     item = SidebarItem(
         name=name,
         icon=icon,
         on_click=on_click,
         item_type=type,
     )
     self.add_child(item)
     return item
Ejemplo n.º 24
0
 def onAddDeck(self) -> None:
     row = self.form.list.currentRow()
     if row < 0:
         default = self.form.filter.text()
     else:
         default = self.names[self.form.list.currentRow()]
     n = getOnlyText(tr(TR.DECKS_NEW_DECK_NAME), default=default)
     n = n.strip()
     if n:
         did = self.mw.col.decks.id(n)
         # deck name may not be the same as user input. ex: ", ::
         self.name = self.mw.col.decks.name(did)
         # make sure we clean up reset hook when manually exiting
         gui_hooks.state_did_reset.remove(self.onReset)
         if self.mw.state == "deckBrowser":
             self.mw.deckBrowser.refresh()
         gui_hooks.sidebar_should_refresh_decks()
         QDialog.accept(self)
Ejemplo n.º 25
0
    def toggleEnabled(self, dir: str, enable: Optional[bool] = None) -> None:
        addon = self.addon_meta(dir)
        should_enable = enable if enable is not None else not addon.enabled
        if should_enable is True:
            conflicting = self._disableConflicting(dir)
            if conflicting:
                addons = ", ".join(self.addonName(f) for f in conflicting)
                showInfo(
                    tr(
                        TR.ADDONS_THE_FOLLOWING_ADDONS_ARE_INCOMPATIBLE_WITH,
                        name=addon.human_name(),
                        found=addons,
                    ),
                    textFormat="plain",
                )

        addon.enabled = should_enable
        self.write_addon_meta(addon)
Ejemplo n.º 26
0
    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
            browser = aqt.dialogs.open("Browser", self.mw)
            browser.form.searchEdit.lineEdit().setText("nid:%d" % nid)
            browser.onSearchActivated()
            showText(err, type="html")
        else:
            tooltip(tr(TR.MEDIA_CHECK_ALL_LATEX_RENDERED))
Ejemplo n.º 27
0
    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(SearchNode(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(SearchNode(deck="*"))
        current = root.add_simple(
            name=tr(TR.BROWSING_CURRENT_DECK),
            icon=icon,
            type=SidebarItemType.DECK,
            on_click=self._filter_func(SearchNode(deck="current")),
        )
        current.id = self.mw.col.decks.selected()

        render(root, tree.children)
Ejemplo n.º 28
0
    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(SearchNode(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(
            SearchNode(negated=SearchNode(tag="none")))
        root.add_simple(
            name=tr(TR.BROWSING_SIDEBAR_UNTAGGED),
            icon=icon,
            type=SidebarItemType.TAG_NONE,
            on_click=self._filter_func(SearchNode(tag="none")),
        )

        render(root, tree.children)
Ejemplo n.º 29
0
    def loadCollection(self) -> bool:
        try:
            return self._loadCollection()
        except Exception as e:
            showWarning(
                tr(TR.ERRORS_UNABLE_OPEN_COLLECTION) + "\n" +
                traceback.format_exc())
            # clean up open collection if possible
            if self.col:
                try:
                    self.col.close(save=False)
                except:
                    pass
                self.col = None

            # return to profile manager
            self.hide()
            self.showProfileManager()
            return False
Ejemplo n.º 30
0
Archivo: sync.py Proyecto: zerrs/anki
def on_full_sync_timer(mw: aqt.main.AnkiQt) -> None:
    progress = mw.col.latest_progress()
    if progress.kind != ProgressKind.FullSync:
        return

    assert isinstance(progress.val, FullSyncProgress)
    if progress.val.transferred == progress.val.total:
        label = tr(TR.SYNC_CHECKING)
    else:
        label = None
    mw.progress.update(
        value=progress.val.transferred,
        max=progress.val.total,
        process=False,
        label=label,
    )

    if mw.progress.want_cancel():
        mw.col.backend.abort_sync()