예제 #1
0
def on_editor_btn_click(editor: Editor, mode: Union[None, str] = None):
    editor.saveNow(lambda: add_pronunciation(editor, mode))
예제 #2
0
def add_pronunciation(editor: Editor, mode: Union[None, str] = None):
    if mode is None:
        modifiers = QApplication.keyboardModifiers()
        if modifiers == Qt.ShiftModifier:
            """Choose top pronunciation automatically when shift key is held down"""
            mode = "auto"

    deck_id = editor.card.did if editor.card is not None else editor.parentWindow.deckChooser.selectedId(
    )

    if editor.note is not None:
        note_type_id = editor.note.mid
    elif editor.card is not None:
        note_type_id = editor.card.note().mid
    else:
        note_type_id = editor.mw.col.models.current()["id"]

    search_field = config.get_note_type_specific_config_object(
        "searchField", note_type_id)
    if search_field is None or search_field.value not in editor.note.keys():
        d = FieldSelector(editor.parentWindow, editor.mw, note_type_id,
                          "searchField", config)
        d.exec()
        search_field = handle_field_select(d, note_type_id, "searchField",
                                           editor)
        if search_field is None:
            return

    audio_field = config.get_note_type_specific_config_object(
        "audioField", note_type_id)
    if audio_field is None or audio_field.value not in editor.note.keys():
        d = FieldSelector(editor.parentWindow, editor.mw, note_type_id,
                          "audioField", config)
        d.exec()
        audio_field = handle_field_select(d, note_type_id, "audioField",
                                          editor)
        if audio_field is None:
            return

    search_field = search_field.value
    audio_field = audio_field.value

    if editor.note is None:
        showInfo(
            "Please enter a search term in the field '" + search_field + "'.",
            editor.widget)
        return

    if mode == 'input':
        query, suc = aqt.utils.getText("Please enter a custom search term:",
                                       editor.widget,
                                       title="Enter custom search term")
        if not suc:
            showWarning("Didn't get any text, please try again.",
                        editor.widget)
            return
    elif editor.note is not None and search_field in editor.note.keys(
    ) and len(editor.note[search_field]) != 0:
        """If available, use the content of the defined search field as the query"""
        query = editor.note[search_field]
    else:
        showInfo(
            "Please enter a search term in the field '" + search_field + "'.",
            editor.widget)
        return

    query = BeautifulSoup(query, "html.parser").text

    if deck_id is not None:
        config_lang = config.get_deck_specific_config_object(
            "language", deck_id)

        if config_lang is None:
            d = LanguageSelector(editor.parentWindow,
                                 mw.col.decks.get(deck_id)["name"])
            d.exec()
            if d.selected_lang is not None:
                config.set_deck_specific_config_object(
                    ConfigObject(name="language",
                                 value=d.selected_lang,
                                 deck=deck_id,
                                 type=OptionType.LANG))
                language = d.selected_lang
            else:
                showInfo(
                    "Cancelled download because no language was selected.")
                return
        else:
            language = config_lang.value

        try:
            forvo = Forvo(query, language, editor.mw,
                          config).load_search_query()
            if forvo is not None:
                results = forvo.get_pronunciations().pronunciations
            else:
                raise NoResultsException()
        except NoResultsException:
            showInfo("No results found! :(", editor.widget)
            return

        hidden_entries_amount = 0
        if config.get_config_object("skipOggFallback").value:
            viable_entries = [p for p in results if not p.is_ogg]
            hidden_entries_amount = len(results) - len(viable_entries)
            if len(viable_entries) == 0:
                showInfo(
                    f"No results found! :(\nThere are {hidden_entries_amount} entries which you chose to skip by deactivating .ogg fallback."
                )
                return
            results = viable_entries

        if mode == "auto":

            def add_automatically(auto_results):
                """If shift key is held down"""
                auto_results.sort(
                    key=lambda result: result.votes)  # sort by votes
                top: Pronunciation = auto_results[
                    len(auto_results) - 1]  # get most upvoted pronunciation
                top.download_pronunciation()  # download that
                try:
                    if config.get_config_object(
                            "audioFieldAddMode").value == "append":
                        """append"""
                        editor.note.fields[get_field_id(
                            audio_field,
                            editor.note)] += "[sound:%s]" % top.audio
                    elif config.get_config_object(
                            "audioFieldAddMode").value == "replace":
                        """replace"""
                        editor.note.fields[get_field_id(
                            audio_field,
                            editor.note)] = "[sound:%s]" % top.audio
                    else:
                        """prepend"""
                        editor.note.fields[get_field_id(
                            audio_field, editor.note
                        )] = "[sound:%s]" % top.audio + editor.note.fields[
                            get_field_id(audio_field, editor.note)]
                except FieldNotFoundException:
                    showWarning(
                        "Couldn't find field '%s' for adding the audio string. Please create a field with this name or change it in the config for the note type id %s"
                        % (audio_field, str(note_type_id)), editor.widget)

                if config.get_config_object(
                        "playAudioAfterSingleAddAutomaticSelection"
                ).value:  # play audio if desired
                    anki.sound.play(top.audio)

                def flush_field():
                    if not editor.addMode:  # save
                        editor.note.flush()
                    editor.currentField = get_field_id(audio_field,
                                                       editor.note)
                    editor.loadNote(
                        focusTo=get_field_id(audio_field, editor.note))

                editor.saveNow(flush_field, keepFocus=True)

            editor.saveNow(functools.partial(add_automatically, results),
                           keepFocus=False)
        else:
            dialog = AddSingle(editor.parentWindow,
                               pronunciations=results,
                               hidden_entries_amount=hidden_entries_amount)
            dialog.exec()

            Forvo.cleanup()
            if dialog.selected_pronunciation is not None:
                try:
                    add_mode = config.get_config_object(
                        "audioFieldAddMode").value
                    if add_mode == "append":
                        editor.note.fields[get_field_id(
                            audio_field, editor.note
                        )] += "[sound:%s]" % dialog.selected_pronunciation.audio
                    elif add_mode == "prepend":
                        editor.note.fields[
                            get_field_id(audio_field,
                                         editor.note)] = "[sound:%s]" % dialog.selected_pronunciation.audio + \
                                                         editor.note.fields[
                                                             get_field_id(audio_field,
                                                                          editor.note)]
                    elif add_mode == "replace":
                        editor.note.fields[get_field_id(
                            audio_field, editor.note
                        )] = "[sound:%s]" % dialog.selected_pronunciation.audio
                except FieldNotFoundException:
                    showWarning(
                        "Couldn't find field '%s' for adding the audio string. Please create a field with this name or change it in the config for the note type id %s"
                        % (audio_field, str(note_type_id)), editor.widget)
                if not editor.addMode:
                    editor.note.flush()
                editor.loadNote()
예제 #3
0
class EditCurrent(QDialog):
    def __init__(self, mw):
        QDialog.__init__(self, None, Qt.Window)
        mw.setupDialogGC(self)
        self.mw = mw
        self.form = aqt.forms.editcurrent.Ui_Dialog()
        self.form.setupUi(self)
        self.setWindowTitle(_("Edit Current"))
        self.setMinimumHeight(400)
        self.setMinimumWidth(500)
        self.form.buttonBox.button(QDialogButtonBox.Close).setShortcut(
            QKeySequence("Ctrl+Return"))
        self.editor = Editor(self.mw, self.form.fieldsArea, self)
        self.editor.card = self.mw.reviewer.card
        self.editor.setNote(self.mw.reviewer.card.note(), focusTo=0)
        restoreGeom(self, "editcurrent")
        addHook("reset", self.onReset)
        self.mw.requireReset()
        self.show()
        # reset focus after open, taking care not to retain webview
        # pylint: disable=unnecessary-lambda
        self.mw.progress.timer(100, lambda: self.editor.web.setFocus(), False)

    def onReset(self):
        # lazy approach for now: throw away edits
        try:
            n = self.editor.note
            n.load()  #reload in case the model changed
        except:
            # card's been deleted
            remHook("reset", self.onReset)
            self.editor.setNote(None)
            self.mw.reset()
            aqt.dialogs.markClosed("EditCurrent")
            self.close()
            return
        self.editor.setNote(n)

    def reopen(self, mw):
        tooltip("Please finish editing the existing card first.")
        self.onReset()

    def reject(self):
        self.saveAndClose()

    def saveAndClose(self):
        self.editor.saveNow(self._saveAndClose)

    def _saveAndClose(self):
        remHook("reset", self.onReset)
        r = self.mw.reviewer
        try:
            r.card.load()
        except:
            # card was removed by clayout
            pass
        else:
            self.mw.reviewer.cardQueue.append(self.mw.reviewer.card)
        self.editor.cleanup()
        self.mw.moveToState("review")
        saveGeom(self, "editcurrent")
        aqt.dialogs.markClosed("EditCurrent")
        QDialog.reject(self)

    def closeWithCallback(self, onsuccess):
        def callback():
            self._saveAndClose()
            onsuccess()

        self.editor.saveNow(callback)