Esempio n. 1
0
def test_genrem():
    d = getEmptyDeck()
    f = d.newNote()
    f['Front'] = u'1'
    f['Back'] = u''
    d.addNote(f)
    assert len(f.cards()) == 1
    m = d.models.current()
    mm = d.models
    # adding a new template should automatically create cards
    t = mm.newTemplate("rev")
    t['qfmt'] = '{{Front}}'
    t['afmt'] = ""
    mm.addTemplate(m, t)
    mm.save(m, templates=True)
    assert len(f.cards()) == 2
    # if the template is changed to remove cards, they'll be removed
    t['qfmt'] = "{{Back}}"
    mm.save(m, templates=True)
    assert len(f.cards()) == 1
    # if we add to the note, a card should be automatically generated
    f.load()
    f['Back'] = "1"
    f.flush()
    assert len(f.cards()) == 2
    # deleteion calls a hook to let the user abort the delete. let's abort it:
    def abort(val, *args):
        return False
    addHook("remEmptyCards", abort)
    f['Back'] = ""
    f.flush()
    assert len(f.cards()) == 2
Esempio n. 2
0
def init():
    mw.mainWin.actionJapaneseAudioDownload = QAction(mw)
    mw.mainWin.actionJapaneseAudioDownloadQuery = QAction(mw)
    icon = QIcon()
    # icon.addPixmap(QPixmap(getLogoFile(u"audio_download.png")),QIcon.Normal,QIcon.Off)
    icon.addPixmap(QPixmap(getLogoFile(u"speaker_down_32.png")),QIcon.Normal,QIcon.Off)
    mw.mainWin.actionJapaneseAudioDownload.setIcon(icon)
    mw.mainWin.actionJapaneseAudioDownload.setIconText(u"Audio Download")
    # Hmm. I don’t really know what the ‘_’ is about. Copy-and-pasted.
    mw.mainWin.actionJapaneseAudioDownload.setShortcut(_("Ctrl+J"))
    mw.mainWin.actionJapaneseAudioDownload.setEnabled(False)
    mw.connect(mw.mainWin.actionJapaneseAudioDownload,SIGNAL("triggered()"),downloadAudio)
    # I really want to jiggle the action for each new card/question.
    # mw.connect(mw,SIGNAL("nextCard()"),toggleDownloadAction)


    mw.mainWin.actionJapaneseAudioDownloadQuery.setIcon(icon)
    mw.mainWin.actionJapaneseAudioDownloadQuery.setIconText(u"Audio Download...")
    mw.mainWin.actionJapaneseAudioDownloadQuery.setShortcut(_("Ctrl+Shift+J"))
    mw.connect(mw.mainWin.actionJapaneseAudioDownloadQuery,SIGNAL("triggered()"),downloadAudioQuery)

    mw.mainWin.menuEdit.addSeparator()

    if not AUTO_DOWNLOAD_AUDIO:
        mw.mainWin.toolBar.addSeparator()
        mw.mainWin.toolBar.addAction(mw.mainWin.actionJapaneseAudioDownload)
        mw.mainWin.menuEdit.addAction(mw.mainWin.actionJapaneseAudioDownload)

    mw.mainWin.menuEdit.addAction(mw.mainWin.actionJapaneseAudioDownloadQuery)


    addHook('disableCardMenuItems', disableDownloadAction)
    addHook('enableCardMenuItems', enableDownloadAction)
Esempio n. 3
0
    def run(self):
        # setup progress handler
        self.byteUpdate = time.time()
        self.recvTotal = 0
        def recvEvent(bytes):
            self.recvTotal += bytes
            self.recv.emit()
        addHook("httpRecv", recvEvent)
        client = AnkiRequestsClient()
        try:
            resp = client.get(
                aqt.appShared + "download/%d" % self.code)
            if resp.status_code == 200:
                data = client.streamContent(resp)
            elif resp.status_code in (403,404):
                self.error = _("Invalid code")
                return
            else:
                self.error = _("Error downloading: %s" % resp.status_code)
                return
        except Exception as e:
            exc = traceback.format_exc()
            try:
                self.error = str(e[0])
            except:
                self.error = str(exc)
            return
        finally:
            remHook("httpRecv", recvEvent)

        self.fname = re.match("attachment; filename=(.+)",
                              resp.headers['content-disposition']).group(1)
        self.data = data
Esempio n. 4
0
 def __init__(self, mw):
     if isMac:
         # use a separate window on os x so we can a clean menu
         QDialog.__init__(self, None, Qt.Window)
     else:
         QDialog.__init__(self, mw)
     QDialog.__init__(self, None, Qt.Window)
     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.connect(self,
                  SIGNAL("rejected()"),
                  self.onSave)
     self.form.buttonBox.button(QDialogButtonBox.Close).setShortcut(
             QKeySequence("Ctrl+Return"))
     self.editor = aqt.editor.Editor(self.mw, self.form.fieldsArea, self)
     self.editor.setNote(self.mw.reviewer.card.note())
     restoreGeom(self, "editcurrent")
     addHook("reset", self.onReset)
     self.mw.requireReset()
     self.show()
     # reset focus after open
     self.editor.web.setFocus()
Esempio n. 5
0
    def run(self):
        # setup progress handler
        self.byteUpdate = time.time()
        self.recvTotal = 0

        def canPost():
            if (time.time() - self.byteUpdate) > 0.1:
                self.byteUpdate = time.time()
                return True

        def recvEvent(bytes):
            self.recvTotal += bytes
            if canPost():
                self.recv.emit()

        addHook("httpRecv", recvEvent)
        con = httpCon()
        try:
            resp, cont = con.request(aqt.appShared + "download/%d" % self.code)
        except Exception, e:
            exc = traceback.format_exc()
            try:
                self.error = unicode(e[0], "utf8", "ignore")
            except:
                self.error = unicode(exc, "utf8", "ignore")
            return
Esempio n. 6
0
 def __init__(self, parent):
     if parent.config['standaloneWindows']:
         windParent = None
     else:
         windParent = parent
     QDialog.__init__(self, windParent, Qt.Window)
     self.parent = parent
     ui.utils.applyStyles(self)
     self.config = parent.config
     self.dialog = ankiqt.forms.addcards.Ui_AddCards()
     self.dialog.setupUi(self)
     self.setWindowTitle(_("Add Items - %s") % parent.deck.name())
     self.setupEditor()
     self.addChooser()
     self.addButtons()
     self.setupStatus()
     self.modelChanged()
     self.addedItems = 0
     self.forceClose = False
     restoreGeom(self, "add")
     restoreSplitter(self.dialog.splitter, "add")
     self.dialog.splitter.setChildrenCollapsible(True)
     self.show()
     addHook('guiReset', self.modelChanged)
     ui.dialogs.open("AddCards", self)
Esempio n. 7
0
 def run(self):
     # setup progress handler
     self.byteUpdate = time.time()
     self.recvTotal = 0
     def canPost():
         if (time.time() - self.byteUpdate) > 0.1:
             self.byteUpdate = time.time()
             return True
     def recvEvent(bytes):
         self.recvTotal += bytes
         if canPost():
             self.recv.emit()
     addHook("httpRecv", recvEvent)
     con =  httpCon()
     try:
         resp, cont = con.request(
             aqt.appShared + "download/%d" % self.code)
     except Exception as e:
         exc = traceback.format_exc()
         try:
             self.error = str(e[0])
         except:
             self.error = str(exc)
         return
     finally:
         remHook("httpRecv", recvEvent)
     if resp['status'] == '200':
         self.error = None
         self.fname = re.match("attachment; filename=(.+)",
                               resp['content-disposition']).group(1)
         self.data = cont
     elif resp['status'] == '403':
         self.error = _("Invalid code.")
     else:
         self.error = _("Error downloading: %s") % resp['status']
Esempio n. 8
0
def addBrowserSelectionCmd( menuLabel, preF, perF, postF, tooltip=None, shortcut=None, progLabel='Working...' ):
    def setupMenu( b ):
        a = QAction( menuLabel, b )
        if tooltip:     a.setStatusTip( tooltip )
        if shortcut:    a.setShortcut( QKeySequence( *shortcut ) )
        b.connect( a, SIGNAL('triggered()'), lambda b=b: doOnSelection( b, preF, perF, postF, progLabel ) )
        b.form.menuEdit.addAction( a )
    addHook( 'browser.setupMenus', setupMenu )
Esempio n. 9
0
def addDoOnSelectionBtn( btnTxt, overviewMsg, progMsg, preF, perF, postF, shortcut=None ):
   def setupMenu( ed ):
      a = QAction( btnTxt, ed )
      if shortcut: a.setShortcut( shortcut )
      ed.connect( a, SIGNAL('triggered()'), lambda e=ed: doOnSelection( e, overviewMsg, progMsg, preF, perF, postF ) )
      if not parentMenu: setupParentMenu( ed )
      parentMenu.addAction( a )
   addHook( 'editor.setupMenus', setupMenu )
Esempio n. 10
0
def addBrowserItem( menuLabel, func_triggered, tooltip=None, shortcut=None):
    def setupMenu( b ):
        a = QAction( menuLabel, b )
        if tooltip:     a.setStatusTip( tooltip )
        if shortcut:    a.setShortcut( QKeySequence( *shortcut ) )
        b.connect( a, SIGNAL('triggered()'), lambda b=b: func_triggered(b) )
        b.form.menuEdit.addAction( a )
    addHook( 'browser.setupMenus', setupMenu )
Esempio n. 11
0
    def setupHooks(self):
        addHook("modSchema", self.onSchemaMod)
        addHook("remNotes", self.onRemNotes)
        addHook("odueInvalid", self.onOdueInvalid)

        addHook("mpvWillPlay", self.onMpvWillPlay)
        addHook("mpvIdleHook", self.onMpvIdle)
        self._activeWindowOnPlay = None
Esempio n. 12
0
 def install(self):
     from anki.hooks import addHook, remHook
     
     # Install hook into focus event of Anki: we regenerate the model information when
     # the cursor moves from the Expression/Reading/whatever field to another field
     log.info("Installing focus hook")
     
     # Unconditionally add our new hook to Anki
     addHook('editFocusLost', self.onFocusLost)
def profileLoaded():
    """Support for Advanced Previewer"""
    try:
        from advanced_previewer.previewer import Previewer
    except ImportError:
        return
    Previewer.linkHandler = wrap(
        Previewer.linkHandler, linkHandler, "around")
    addHook("previewerMungeQA", linkInserter)
Esempio n. 14
0
 def __init__(self, mw):
     self.mw = mw
     self.web = mw.web
     self.card = None
     self.cardQueue = []
     self.hadCardQueue = False
     self._answeredIds = []
     self.state = None
     self.bottom = aqt.toolbar.BottomBar(mw, mw.bottomWeb)
     addHook("leech", self.onLeech)
Esempio n. 15
0
 def __init__(self, mw, widget, label=True, start=None):
     QHBoxLayout.__init__(self)
     self.widget = widget
     self.mw = mw
     self.label = label
     self.setMargin(0)
     self.setSpacing(8)
     self.setupDecks()
     self.widget.setLayout(self)
     addHook('currentModelChanged', self.onModelChange)
Esempio n. 16
0
 def __init__(self, mw):
     self.mw = mw
     self.web = mw.web
     self.card = None
     self.cardQueue = []
     self._answeredIds = []
     self.state = None
     self.keep = False
     self._setupStatus()
     addHook("leech", self.onLeech)
Esempio n. 17
0
 def __init__(self, mw, widget, label=True):
     QHBoxLayout.__init__(self)
     self.widget = widget
     self.mw = mw
     self.deck = mw.col
     self.label = label
     self.setMargin(0)
     self.setSpacing(8)
     self.setupModels()
     addHook('reset', self.onReset)
     self.widget.setLayout(self)
Esempio n. 18
0
 def __init__(self, mw, widget, label=True):
     QHBoxLayout.__init__(self)
     self.widget = widget
     self.mw = mw
     self.currentModel = sendToAnki("modelByName", {"name": "Basic"})
     self.label = label
     self.setMargin(0)
     self.setSpacing(8)
     self.setupModels()
     addHook('reset', self.onReset)
     self.widget.setLayout(self)
Esempio n. 19
0
def init_kanji_info():
    kanji_info_txt = os.path.join(mw.pm.addonFolder(), "kanji_info.txt")
    read_kanji_info(kanji_info_txt)

    if not len(kanji_info):
        # gracefully also check Anki main dir
        print "kanji_info", kanji_info_version, "please put kanji_info.txt in", kanji_info_txt

    print "kanji_info", kanji_info_version, "found", len(kanji_info), "entries"

    if len(kanji_info):
        addHook("showAnswer", append_kanji_info)
Esempio n. 20
0
 def __init__(self, mw):
     self.mw = mw
     self.web = mw.web
     self.card = None
     self.cardQueue = []
     self.hadCardQueue = False
     self._answeredIds = []
     self._recordedAudio = None
     self.typeCorrect = None # web init happens before this is set
     self.state = None
     self.bottom = aqt.toolbar.BottomBar(mw, mw.bottomWeb)
     addHook("leech", self.onLeech)
Esempio n. 21
0
def setup_tips():
    read_character_data()
    read_scripts()
    # addHook("filterQuestionText", show_tip_filter)
    ## Uncomment the line above to also show tips on the question.
    addHook("filterAnswerText", show_tip_filter)

    ## Looks like we cant just load scripts. So eval them after we've
    ## done the rest of the card.
    # addHook("showQuestion", do_scripts)
    ## Uncomment the line above to also show tips on the question.
    addHook("showAnswer", do_scripts)
Esempio n. 22
0
def ht_init():
    global ht_menu
    addHook("profileLoaded",ht_load)
    addHook("unloadProfile",ht_save)
    ht_menu = QAction("Hide Button Times", mw, checkable=True)
    ht_menu.triggered.connect(ht_switch)
    try:
        mw.addon_view_menu
    except AttributeError:
        mw.addon_view_menu = QMenu(_(u"&View"), mw)
        mw.form.menubar.insertMenu(mw.form.menuTools.menuAction(),
                                   mw.addon_view_menu)
        mw.addon_view_menu.addAction(ht_menu)
Esempio n. 23
0
 def __init__(self, browser, nids):
     QDialog.__init__(self, browser)
     self.browser = browser
     self.nids = nids
     self.oldModel = browser.card.note().model()
     self.form = aqt.forms.changemodel.Ui_Dialog()
     self.form.setupUi(self)
     self.setWindowModality(Qt.WindowModal)
     self.setup()
     restoreGeom(self, "changeModel")
     addHook("reset", self.onReset)
     addHook("currentModelChanged", self.onReset)
     self.exec_()
Esempio n. 24
0
 def __init__(self, mw):
     # Right, this is more than a bit weird. The basic issue is that if we were
     # to just initialize() RIGHT NOW then we will hold the Python import lock,
     # because Anki __import__s its plugins. This ABSOLUTELY KILLS us when we
     # come to e.g. build the database on a background thread, because that code
     # naturally wants to import some stuff, but it doesn't hold the lock!
     #
     # To work around this issue, we carefully schedule initialization (and database
     # construction) for a time when Anki will not have caused us to hold the import lock.
     #
     # Debugging this was a fair bit of work!
     from anki.hooks import addHook
     addHook("init", lambda: self.initialize(mw))
Esempio n. 25
0
def nm_onload():
	"""
	Add hooks and initialize menu.
	Call to this function is placed on the end of this file.
	"""

	nm_refresh_css_custom_colors_string()

	addHook("unloadProfile", nm_save)
	addHook("profileLoaded", nm_load)
	addHook("showQuestion", take_care_of_night_class)
	addHook("showAnswer", take_care_of_night_class)
	nm_setup_menu()

	Browser.__init__ = wrap(Browser.__init__, nm_browser_init_after)
	Editor._addButton = wrap(Editor._addButton, nm_add_button_name, "around")
	Editor.checkValid = wrap(Editor.checkValid, nm_style_fields)
	Editor.__init__ = wrap(Editor.__init__, nm_editor_init_after)

	# Anki 2.1 Deck Browser background colour
	if appVersion.startswith('2.1'):
		Editor._loadFinished = wrap(Editor._loadFinished, nm_editor_loadFinished)
	EditorWebView.setHtml = wrap(EditorWebView.setHtml, nm_editor_web_view_set_html_after)
	Browser._renderPreview = wrap(Browser._renderPreview, nm_edit_render_preview_after)
	Browser._cardInfoData = wrap(Browser._cardInfoData, nm_browser_card_info_after, "around")
	EditCurrent.__init__ = wrap(EditCurrent.__init__, nm_edit_current_init_after)
	AddCards.__init__ = wrap(AddCards.__init__, nm_add_init_after)
	CardLayout.renderPreview = wrap(CardLayout.renderPreview, nm_render_preview_after)
Esempio n. 26
0
 def __init__(self, mw, widget, cards=True, label=True):
     QHBoxLayout.__init__(self)
     self.widget = widget
     self.mw = mw
     self.deck = mw.deck
     self.handleCards = cards
     self.label = label
     self._ignoreReset = False
     self.setMargin(0)
     self.setSpacing(4)
     self.setupModels()
     self.setupTemplates()
     addHook('reset', self.onReset)
     self.widget.setLayout(self)
Esempio n. 27
0
 def __init__(self, mw, names=None, accept=None, title=None,
              help="studydeck", current=None, cancel=True,
              parent=None, dyn=False, buttons=[], geomKey="default"):
     QDialog.__init__(self, parent or mw)
     self.mw = mw
     self.form = aqt.forms.studydeck.Ui_Dialog()
     self.form.setupUi(self)
     self.form.filter.installEventFilter(self)
     self.cancel = cancel
     addHook('reset', self.onReset)
     self.geomKey = "studyDeck-"+geomKey
     restoreGeom(self, self.geomKey)
     if not cancel:
         self.form.buttonBox.removeButton(
             self.form.buttonBox.button(QDialogButtonBox.Cancel))
     if buttons:
         for b in buttons:
             self.form.buttonBox.addButton(b, QDialogButtonBox.ActionRole)
     else:
         b = QPushButton(_("Add"))
         b.setShortcut(QKeySequence("Ctrl+N"))
         b.setToolTip(shortcut(_("Add New Deck (Ctrl+N)")))
         self.form.buttonBox.addButton(b, QDialogButtonBox.ActionRole)
         b.connect(b, SIGNAL("clicked()"), self.onAddDeck)
     if title:
         self.setWindowTitle(title)
     if not names:
         names = sorted(self.mw.col.decks.allNames(dyn=dyn))
         self.nameFunc = None
         self.origNames = names
     else:
         self.nameFunc = names
         self.origNames = names()
     self.name = None
     self.ok = self.form.buttonBox.addButton(
         accept or _("Study"), QDialogButtonBox.AcceptRole)
     self.setWindowModality(Qt.WindowModal)
     self.connect(self.form.buttonBox,
                  SIGNAL("helpRequested()"),
                  lambda: openHelp(help))
     self.connect(self.form.filter,
                  SIGNAL("textEdited(QString)"),
                  self.redraw)
     self.connect(self.form.list,
                  SIGNAL("itemDoubleClicked(QListWidgetItem*)"),
                  self.accept)
     self.show()
     # redraw after show so position at center correct
     self.redraw("", current)
     self.exec_()
Esempio n. 28
0
def anknotes_onload():
    # write_file_contents('%s: anknotes_onload' % __name__, 'load')
    if in_anki():
        addHook("profileLoaded", anknotes_profile_loaded)
        if ANKNOTES.HOOKS.DB:
            DB.scalar = anknotes_scalar # wrap(DB.scalar, anknotes_scalar, "before")
            DB.execute = wrap(DB.execute, anknotes_execute, "before")
        if ANKNOTES.HOOKS.SEARCH:
            addHook("search", anknotes_search_hook)
            Finder._query = wrap(Finder._query, anknotes_finder_query_wrap, "around")
            Finder.findCards = wrap(Finder.findCards, anknotes_finder_findCards_wrap, "around")
            browser.Browser._systemTagTree = wrap(browser.Browser._systemTagTree, anknotes_browser_tagtree_wrap, "around")
        # write_file_contents('%s: anknotes_onload: anknotes_setup_menu' % __name__, 'load')
        menu.anknotes_setup_menu()
        Preferences.setupOptions = wrap(Preferences.setupOptions, settings.setup_evernote)
Esempio n. 29
0
 def __init__(self):
     self.languages = dict()
     self.preferences = Preferences()
     self.preferences.load()
     if not self.loadLanguages():
         def downloadDictionaries():
             showInfo(_("No Yomichan dictionaries found\nDownloading now"))
             ret = download(aqt.mw, 2027900559)
             if not ret:
                 raise Exception("Could not download dictionary files")
             data, fname = ret
             aqt.mw.addonManager.install(data, fname)
             aqt.mw.progress.finish()
         addHook('profileLoaded',downloadDictionaries)
     self.loadSubscriptions()
Esempio n. 30
0
 def __init__(self, mw):
     self.mw = mw
     self.web = mw.web
     self.card = None
     self.cardQueue = []
     self.hadCardQueue = False
     self._answeredIds = []
     self._recordedAudio = None
     self.typeCorrect = None # web init happens before this is set
     self.state = None
     self.bottom = aqt.toolbar.BottomBar(mw, mw.bottomWeb)
     # qshortcut so we don't autorepeat
     self.delShortcut = QShortcut(QKeySequence("Delete"), self.mw)
     self.delShortcut.setAutoRepeat(False)
     self.mw.connect(self.delShortcut, SIGNAL("activated()"), self.onDelete)
     addHook("leech", self.onLeech)
Esempio n. 31
0
import ssl
import sys

from anki.hooks import addHook
from anki.utils import isMac

sys.dont_write_bytecode = True
if isMac:
    ssl._create_default_https_context = ssl._create_unverified_context

############## other config here ##################
shortcut = ('Ctrl+Alt' if isMac else 'Ctrl') + '+Q'

###################################################


def start_here():
    from . import common as fastwq
    from .context import config
    config.read()
    fastwq.my_shortcut = shortcut
    if not fastwq.have_setup:
        fastwq.have_setup = True
        fastwq.config_menu()
        fastwq.browser_menu()
        fastwq.context_menu()
        fastwq.customize_addcards()


addHook("profileLoaded", start_here)
Esempio n. 32
0
def deckStatsInit21(self, mw):
    self.form.web.onBridgeCmd = self._linkHandler
    # refresh heatmap on options change:
    addHook('reset', self.refresh)
                        newf = self.stripNewLines(newf)
                        newf = TAB + TAB + newf.replace("\n", "\n" + TAB + TAB)
                        latexnote.append(TAB + r"\begin{plain}" + "\n" + newf +
                                         "\n" + TAB + r"\end{plain}")
            #remove empty fields at the end of the note:
            while latexnote[-1] == TAB + r"\xplain{}":
                latexnote.pop()
            # tags
            if self.includeTags:
                cleantag = tags.strip()
                if cleantag != "":
                    latexnote.append(TAB + r"\tags{" + tags.strip() + r"}")
            latexnote.append(r"\end{note}" + "\n")
            data.append("\n".join(latexnote))
        self.count = len(data)
        #preamble =r"""# -- I've decided that this should be placed in model["latexPre"] by the user
        #\newenvironment{note}{}{\begin{center}\rule{\textwidth}{2pt}\end{center}}
        #\newenvironment{field}{}{\begin{center}\rule{\textwidth}{0.4pt}\end{center}}
        #\newcommand*{\tags}[1]{\paragraph{tags: }#1}"""
        out = "% -*- coding: utf-8 -*-\n" + model[
            "latexPre"] + "\n" + "\n".join(data) + "\n" + model["latexPost"]
        file.write(out.encode("utf-8"))


def addLatexExporterToList(exps):
    exps.append((LatexNoteExporter.key + " (*" + LatexNoteExporter.ext + r")",
                 LatexNoteExporter))


addHook("exportersList", addLatexExporterToList)
Esempio n. 34
0
def run():

    def setupMenu(self):
        # menu = self.form.menuEdit
        menu = QtWidgets.QMenu('AutoFields', self.form.menubar)

        if language == 'french':
            a = menu.addAction('Conjugate French Verbs')
            a.triggered.connect(lambda _, b=self: setVerbConjugationsForOneNoteFromBrowser(b))
            a.setIcon(conj_icon)
            menu.addSeparator()

            b = menu.addAction('Get all extra fields')
            b.triggered.connect(lambda _, b=self: populateExtraFields(b))
            b.setIcon(all_icon)
            menu.addSeparator()

            c = menu.addAction('Get Etymology')
            c.triggered.connect(lambda _, c=self: populateEtymology(c))
            c.setIcon(etymology_icon)

            d = menu.addAction('Get IPA')
            d.triggered.connect(lambda _, d=self: populateIPA(d))
            d.setIcon(ipa_icon)

            e = menu.addAction('Get Audio')
            e.triggered.connect(lambda _, e=self: populateAudio(e))
            e.setIcon(audio_icon)

            f = menu.addAction('Get POS')
            f.triggered.connect(lambda _, f=self: populatePos(f))
            f.setIcon(pos_icon)

            g = menu.addAction('Get Plural')
            g.triggered.connect(lambda _, g=self: populatePlural(g))
            g.setIcon(plural_icon)

            h = menu.addAction('Get Feminine')
            h.triggered.connect(lambda _, h=self: populateFeminine(h))
            h.setIcon(feminine_icon)
            menu.addSeparator()


            showAbout = QAction("About", mw)
            showAbout.triggered.connect(show_info)
            showAbout.setIcon(about_icon)
            menu.addAction(showAbout)


            self.form.menubar.addMenu(menu)

        else:
            c = menu.addAction('Etymology')
            c.triggered.connect(lambda _, c=self: populateEtymology(c))
            c.setIcon(etymology_icon)

            d = menu.addAction('IPA')
            d.triggered.connect(lambda _, d=self: populateIPA(d))
            d.setIcon(ipa_icon)

            e = menu.addAction('Audio')
            e.triggered.connect(lambda _, e=self: populateAudio(e))
            e.setIcon(audio_icon)

            f = menu.addAction('POS')
            f.triggered.connect(lambda _, f=self: populatePos(f))
            f.setIcon(pos_icon)

            g = menu.addAction('Plural')
            g.triggered.connect(lambda _, g=self: populatePlural(g))
            g.setIcon(plural_icon)
            self.form.menubar.addMenu(menu)


            showAbout = QAction("About", mw)
            showAbout.triggered.connect(show_info)
            showAbout.setIcon(about_icon)
            menu.addAction(showAbout)

    addHook("browser.setupMenus", setupMenu)
Esempio n. 35
0
    global addon_path
    global addonfoldername
    global addonname
    global css_templates_folder
    global mediafolder
    global css_file_in_media
    addon_path = os.path.dirname(__file__)
    addonfoldername = os.path.basename(addon_path)
    addonname = mw.addonManager.addonName(addonfoldername)
    css_templates_folder = os.path.join(addon_path, "css")
    mediafolder = os.path.join(mw.pm.profileFolder(), "collection.media")
    css_file_in_media = os.path.join(mediafolder,
                                     "_styles_for_syntax_highlighting.css")


addHook("profileLoaded", set_some_paths)

insertscript = """<script>
function MyInsertHtml(content) {
    var s = window.getSelection();
    var r = s.getRangeAt(0);
    r.collapse(true);
    var mydiv = document.createElement("div");
    mydiv.innerHTML = content;
    r.insertNode(mydiv);
    // Move the caret
    r.setStartAfter(mydiv);
    r.collapse(true);
    s.removeAllRanges();
    s.addRange(r);
}
Esempio n. 36
0
from anki.hooks import addHook
from aqt import mw

from .config import *


def easeAdjustFunc():
    mw.reviewer.card.factor = ease_factor


addHook('showQuestion', easeAdjustFunc)
addHook('showAnswer', easeAdjustFunc)
Esempio n. 37
0
    if path.split('.')[-1] != "db":
        infoMsg('The selected file was not a db file')
        return # per() and post() will still execute, but nothing happens

    db = MorphDb( path )
    return { 'b':b, 'db':db, 'tags':str(tags), 'noteCount':noteCount }

def per( st, n ): # :: State -> Note -> State
    notecfg = getFilter(n)
    if notecfg is None: return st
    morphemizer = getMorphemizerByName(notecfg['Morphemizer'])
    for field in notecfg['Fields']:
        for m in getMorphemes(morphemizer, n[ field ], n.tags):
            if m in st['db'].db:
                n.addTag(st['tags'])
                break
    n.flush()
    return st

def post( st ): # :: State -> State
    tooltip(_( 'Tagged {} notes containing morphemes in the selected db with "{}" '.format(st['noteCount'], st['tags']) ) )
    return st

def runBatchPlay():
    label = 'MorphMan: Mass Tagger'
    tooltipMsg = 'Tag all cards that contain morphemes from db'
    shortcut = cfg1('set mass tagger key')
    addBrowserNoteSelectionCmd( label, pre, per, post, tooltip=tooltipMsg, shortcut=(shortcut,) )

addHook( 'profileLoaded', runBatchPlay )
Esempio n. 38
0
        # if we're editing an existing card, flush the changes
        if note.id != 0:
            note.flush()
        return True

    return flag


# Add a colorized kanji to a Diagram whenever leaving a Kanji field


def onFocusLost(flag, note, currentFieldIndex):
    return addKanji(note, flag, currentFieldIndex)


addHook('editFocusLost', onFocusLost)

# menu item to regenerate all


def regenerate_all():
    # Find the models that have the right name and fields; faster than
    # checking every note
    if not askUser("Do you want to regenerate all kanji diagrams? "
                   'This may take some time and will overwrite the '
                   'destination Diagram fields.'):
        return
    models = [m for m in mw.col.models.all() if modelIsCorrectType(m)]
    # Find the notes in those models and give them kanji
    for model in models:
        for nid in mw.col.models.nids(model):
Esempio n. 39
0
 def __addHooks(self):
           
     addHook('fmod_jparser', self.injectParser)
     addHook('fmod_jparser2', self.injectParser2)
     addHook('fmod_jparser3', self.injectParser3)
     addHook("showAnswer", self.showAnswer) 
Esempio n. 40
0
    global flag
    flag = True

def _showQuestion():
    global jsObjectJParser, flag
    if flag:
        flag = False
        mw.web.page().mainFrame().addToJavaScriptWindowObject("pluginObjectJParser", jsObjectJParser)

if anki.version < "2.1":
    mw.reviewer._initWeb=wrap(mw.reviewer._initWeb,_initWeb,"before")
    mw.reviewer._showQuestion=wrap(mw.reviewer._showQuestion,_showQuestion,"before")


#addHook("profileLoaded", addToMenuBar)
addHook("profileLoaded", kanji.load)
addHook("unloadProfile", kanji.unload)

action_label = "Reload Parser"
action = None
for a in mw.form.menuTools.actions():
    if a.text() == action_label:
        action = a

if action:
    action.triggered.disconnect()
else:
    action = QAction(action_label, mw)
    mw.form.menuTools.addAction(action)
action.triggered.connect(kanji.load)
Esempio n. 41
0
mw.form.actionFullDatabaseCheck.setIcon(
    QIcon(os.path.join(icons_dir, 'check-db.png')))
mw.form.actionPreferences.setIcon(
    QIcon(os.path.join(icons_dir, 'preferences.png')))

## Hide the edit and nmore buttons.
mw.reviewer._bottomCSS += "td.stat button {display:none;}"

# Create the menus
add_tool_bar()
add_more_tool_bar()
add_to_menus()
#mw.toolbar.web.hide()
mw.deckBrowser.show = wrap(mw.deckBrowser.show, edit_actions_off)
mw.overview.show = wrap(mw.overview.show, edit_actions_on)
mw.reviewer.show = wrap(mw.reviewer.show, edit_actions_on)
mw.reviewer.show = wrap(mw.reviewer.show, maybe_more_tool_bar_on)
mw.overview.show = wrap(mw.overview.show, more_tool_bar_off)
mw.reviewer._toggleStar = wrap(mw.reviewer._toggleStar, update_mark_action)
mw.deckBrowser.show = wrap(mw.deckBrowser.show, more_tool_bar_off)

# Wrapper to not show a next card.
original_next_card = Reviewer.nextCard
Reviewer.nextCard = next_card_wrapper

# Make sure we don't leave a stale last card button switched on
addHook("reviewCleanup", next_card_toggle_off)

addHook("unloadProfile", save_toolbars_visible)
addHook("profileLoaded", load_toolbars_visible)
def onEditWindow(self):
    """Launch BrowserEditCurrent instance"""
    nids = self.selectedNotes()
    if len(nids) != 1:
        return
    self.form.splitter.widget(1).setVisible(False)
    self.editor.setNote(None)
    self.externalNid = nids[0]
    self.editCurrent = aqt.dialogs.open("BrowserEditCurrent", self.mw, self)

def onSetupMenus(self):
    """Create menu entry and set attributes up"""
    menu = self.form.menuEdit
    menu.addSeparator()
    a = menu.addAction('Edit in New Window')
    a.setShortcut(QKeySequence("Ctrl+Alt+E"))
    a.triggered.connect(lambda _, o=self: onEditWindow(o))
    self.externalNid = None
    self.editCurrent = None

# Register new dialog in DialogManager:
dialogs._dialogs["BrowserEditCurrent"] = [BrowserEditCurrent, None]

# Hook into menu setup
addHook("browser.setupMenus", onSetupMenus)

# Modify existing methods
Browser.onRowChanged = wrap(Browser.onRowChanged, onRowChanged, "after")
Browser.deleteNotes = wrap(Browser.deleteNotes, onDeleteNotes, "before")
        tooltip(f'Added tag(s) "%s"{tooltipSuffix}' % map['tags'])

    return r


def new_shortcutKeys():
    tag_shortcut = getConfig().get("add tag shortcut", "q")
    tag_edit_shortcut = getConfig().get("edit tag shortcut", "w")
    quick_tags = getConfig().get("quick tags", dict())  # end quick_tags
    sk = [(tag_shortcut, promptAndAddTags),
          (tag_edit_shortcut, promptAndEditTags)]
    for key, map in quick_tags.items():
        sk.append((key, quick_tag_method(map)))
    return sk


def addShortcuts(shortcuts):
    usedShortcuts = {presentShortcut: fn for presentShortcut, fn in shortcuts}
    newShortcuts = new_shortcutKeys()
    for shortcut, fn in newShortcuts:
        if shortcut not in usedShortcuts:
            shortcuts.append((shortcut, fn))
            usedShortcuts[shortcut] = fn
        else:
            tooltip(
                f"Warning: shortcut {shortcut} is already used by {usedShortcuts[shortcut]}. Please change it by editing quick tagging's configuration file."
            )


addHook("reviewStateShortcuts", addShortcuts)
Esempio n. 44
0
            changed += 1
        mw.progress.update(label="Processed %d/%d notes" % (c + 1, len(nids)))
    return changed


# true on change
def _fixNoteHTML(note):
    changed = False
    for fld, val in note.items():
        parsed = str(BeautifulSoup(val, "html.parser"))
        if parsed != val:
            note[fld] = parsed
            changed = True

    if changed:
        note.flush()

    return changed


def onMenuSetup(browser):
    act = QAction(browser)
    act.setText("Fix Invalid HTML")
    mn = browser.form.menu_Notes
    mn.addSeparator()
    mn.addAction(act)
    act.triggered.connect(lambda b=browser: onFixHTML(browser))


addHook("browser.setupMenus", onMenuSetup)
Esempio n. 45
0
        log.close()


def _errMsg(type, texpath):
    """An error message, in html, concerning LaTeX compilation.

    This message contains LaTeX outputs if it exists, or a message
    asking whether the program latex and dvipng/dvisvgm are installed.

    Keyword arguments
    type -- the (begin of the) executed command 
    texpath -- the path to the (temporary) file which was compiled
    """
    msg = (_("Error executing %s.") % type) + "<br>"
    msg += (_("Generated file: %s") % texpath) + "<br>"
    try:
        with open(namedtmp("latex_log.txt", rm=False)) as f:
            log = f.read()
        if not log:
            raise Exception()
        msg += "<small><pre>" + html.escape(log) + "</pre></small>"
    except:
        msg += _("Have you installed latex and dvipng/dvisvgm?")
    return msg


# setup q/a filter
addHook("mungeQA", mungeQA)
#This hook is called collection._renderQA. See mungeQA comment to know
#the parameters
Esempio n. 46
0
    note["Pinyin"] = note["Pinyin"].rstrip()

    return True


def on_focus_lost(flag, note, _fidx):
    """ Takes filled in hanzi field and matches empty fields with their
        respective information """

    if "Chinese" not in note.model()['name']:
        return flag
    if not note["Hanzi"] or note["Pinyin"] or note["Meaning"]:
        return flag

    cursor = CONN.cursor()
    cursor.execute("SELECT * FROM entries WHERE simplified = ? LIMIT 1",
                   (note["Hanzi"], ))
    entry = cursor.fetchone()
    if entry is None:
        cursor.close()
        return multiple_hanzi(note, flag)

    note["Pinyin"] = entry[2]
    note["Meaning"] = entry[3].replace("/", "<br>")
    cursor.close()

    return True


addHook('editFocusLost', on_focus_lost)
Esempio n. 47
0
    print(obj)
    item = obj.form.menu_Cards

    def register_action(*actArgs, trigger):
        "Automatically handles cleanup registration for reloading"
        action = item.addAction(*actArgs)
        prev_actions.append((item, action))
        action.triggered.connect(lambda _: trigger(obj))
        return action

    o_card = register_action("Use as ordering card",
                             trigger=search_ordering_card)
    o_card.setShortcut(QKeySequence("Ctrl+Shift+O"))

    c_card = register_action("Confirm matching card",
                             trigger=confirm_matching_card)

    if get_reload_enabled():
        rl_card = register_action("Reload Card_Transformer Extension",
                                  trigger=reload_extension)
        rl_card.setShortcut(QKeySequence("Ctrl+Shift+E"))


# clear previous menu hook to prevent duplicate menu items being added across browser sessions
try:
    remHook("browser.setupMenus", prev_menu_hook)
except NameError:
    prev_menu_hook = None
addHook("browser.setupMenus", setup_menus)
prev_menu_hook = setup_menus
Esempio n. 48
0
                random.choice(string.ascii_letters + string.digits)
                for n in range(32)
            ]) + '"'

        def randomizeId(s):
            return re.sub(r' +id *= *[\'"]*([^ \'">]+)[\'"]*', getRandomId, s,
                          0, re.IGNORECASE)

        out = ""

        for cid in ids:
            c = self.col.getCard(cid)

            out += '<div class="Card">\n'
            out += '<div class="Question">\n' + esc(c.q()) + "\n</div>\n"
            out += '<div class="Answer">\n' + esc(c.a()) + "\n</div>\n"
            out += "</div><!-- Card -->\n\n"

        out = self.htmlBefore + out + self.htmlAfter
        file.write(out.encode("utf-8"))


def addMyExporter(exps):
    def theid(obj):
        return ("%s (*%s)" % (obj.key, obj.ext), obj)

    exps.append(theid(MyTextCardExporter))


addHook("exportersList", addMyExporter)
Esempio n. 49
0
 def accept(self):
     self.exporter.includeSched = (self.frm.includeSched.isChecked())
     self.exporter.includeMedia = (self.frm.includeMedia.isChecked())
     self.exporter.includeTags = (self.frm.includeTags.isChecked())
     if not self.frm.deck.currentIndex():
         self.exporter.did = None
     else:
         name = self.decks[self.frm.deck.currentIndex()]
         self.exporter.did = self.col.decks.id(name)
     if (self.isApkg and self.exporter.includeSched
             and not self.exporter.did):
         verbatim = True
         # it's a verbatim apkg export, so place on desktop instead of
         # choosing file; use homedir if no desktop
         usingHomedir = False
         file = os.path.join(
             QDesktopServices.storageLocation(
                 QDesktopServices.DesktopLocation), "collection.apkg")
         if not os.path.exists(os.path.dirname(file)):
             usingHomedir = True
             file = os.path.join(
                 QDesktopServices.storageLocation(
                     QDesktopServices.HomeLocation), "collection.apkg")
         if os.path.exists(file):
             if usingHomedir:
                 question = _(
                     "%s already exists in your home directory. Overwrite it?"
                 )
             else:
                 question = _(
                     "%s already exists on your desktop. Overwrite it?")
             if not askUser(question % "collection.apkg"):
                 return
     else:
         verbatim = False
         # Get deck name and remove invalid filename characters
         deck_name = self.decks[self.frm.deck.currentIndex()]
         deck_name = re.sub('[\\\\/?<>:*|"^]', '_', deck_name)
         filename = os.path.join(
             aqt.mw.pm.base, u'{0}{1}'.format(deck_name, self.exporter.ext))
         while 1:
             file = getSaveFile(self,
                                _("Export"),
                                "export",
                                self.exporter.key,
                                self.exporter.ext,
                                fname=filename)
             if not file:
                 return
             if checkInvalidFilename(os.path.basename(file), dirsep=False):
                 continue
             break
     self.hide()
     if file:
         self.mw.progress.start(immediate=True)
         try:
             f = open(file, "wb")
             f.close()
         except (OSError, IOError), e:
             showWarning(_("Couldn't save file: %s") % unicode(e))
         else:
             os.unlink(file)
             exportedMedia = lambda cnt: self.mw.progress.update(
                 label=ngettext("Exported %d media file",
                                "Exported %d media files", cnt) % cnt)
             addHook("exportedMediaFiles", exportedMedia)
             self.exporter.exportInto(file)
             remHook("exportedMediaFiles", exportedMedia)
             if verbatim:
                 if usingHomedir:
                     msg = _(
                         "A file called %s was saved in your home directory."
                     )
                 else:
                     msg = _("A file called %s was saved on your desktop.")
                 msg = msg % "collection.apkg"
                 period = 5000
             else:
                 period = 3000
                 if self.isTextNote:
                     msg = ngettext(
                         "%d note exported.", "%d notes exported.",
                         self.exporter.count) % self.exporter.count
                 else:
                     msg = ngettext(
                         "%d card exported.", "%d cards exported.",
                         self.exporter.count) % self.exporter.count
             tooltip(msg, period=period)
         finally:
Esempio n. 50
0
            return showWarning(
                r"""<p>Please install <a href='https://mpv.io'>mpv</a>.</p>
                On Windows download mpv and either update PATH environment variable or put mpv.exe in Anki installation folder (C:\Program Files\Anki).""",
                parent=mw)
    else:
        _player(path)


def _stopPlayer():
    global p

    if p != None and p.poll() is None:
        p.kill()


addHook("unloadProfile", _stopPlayer)
atexit.register(_stopPlayer)


def clearExternalQueue():
    global _queueEraser

    _stopPlayer()
    _queueEraser()


_player = s._player
s._player = queueExternal

_queueEraser = s._queueEraser
s._queueEraser = clearExternalQueue
Esempio n. 51
0
    clayout.forms[-1]['pform'].frontWeb.setLinkHandler(simple_link_handler)
    clayout.forms[-1]['pform'].backWeb.setLinkHandler(simple_link_handler)


def add_preview_link_handler(browser):
    u"""Make sure we play the files from the preview window."""
    browser._previewWeb.setLinkHandler(simple_link_handler)


def reduce_format_qa(self, text):
    u"""Remove elements with a given class before displaying."""
    soup = BeautifulSoup(text)
    for hide in soup.findAll(
            True, {'class': re.compile('\\b' + hide_class_name + '\\b')}):
        hide.extract()
    return original_format_qa(self, unicode(soup))


original_review_link_handler = Reviewer._linkHandler
Reviewer._linkHandler = review_link_handler_wrapper

original_format_qa = DataModel.formatQA
DataModel.formatQA = reduce_format_qa

old_css = Card.css
Card.css = svg_css

addHook("mungeQA", play_button_filter)
Browser._openPreview = wrap(Browser._openPreview, add_preview_link_handler)
CardLayout.addTab = wrap(CardLayout.addTab, add_clayout_link_handler)
Esempio n. 52
0
    mw.reset()
    mw.progress.finish()
    tooltip(_("""Prefix removed."""))


def setupMenu(browser):
    a = QAction("Add prefix", browser)
    shortcut = getConfig("Shortcut: Add prefix", "Ctrl+Alt+P")
    if shortcut:
        a.setShortcut(QKeySequence(shortcut))
    a.triggered.connect(lambda: onAddPrefix(browser))
    browser.form.menuEdit.addAction(a)
    shortcut = getConfig("Shortcut: Remove prefix", "Ctrl+Shift+Alt+P")
    if shortcut:
        a.setShortcut(QKeySequence(shortcut))
    a = QAction("Remove prefix", browser)
    a.setShortcut(QKeySequence("Ctrl+Shift+Alt+P"))
    a.triggered.connect(lambda: onRemovePrefix(browser))
    browser.form.menuEdit.addAction(a)


def onAddPrefix(browser):
    addPrefix(browser.selectedCards())


def onRemovePrefix(browser):
    removePrefix(browser.selectedCards())


addHook("browser.setupMenus", setupMenu)
Esempio n. 53
0
 def __init__(self):
     addHook('setupEditorButtons', self.setupButton)
     addHook('loadNote', self.updateButton)
     addHook('editFocusLost', self.onFocusLost)
Esempio n. 54
0
    """
        returns the modules base directory
        """

    directory = os.path.dirname(os.path.abspath(__file__))
    results = directory.split('\\')
    tail = results[-1].lower()

    while tail != 'vocabolaudioscraper':
        directory = os.path.dirname(os.path.abspath(directory))
        results = directory.split('\\')
        tail = results[-1].lower()

    return directory


def addEditorButton(buttons, editor):
    """
    creates a new button
    returns new set of buttons
    """

    editor._links['data'] = get_data
    path = get_base_directory()
    icon = path + '/resources/icon.png'

    return buttons + [editor._addButton(icon, 'data', 'get audio')]


addHook('setupEditorButtons', addEditorButton)
Esempio n. 55
0

def reduce_format_qa(self, text):
    u"""Remove elements with a given class before displaying."""
    soup = BeautifulSoup(text, 'html.parser')
    for hide in soup.findAll(
            True, {'class': re.compile('\\b' + hide_class_name + '\\b')}):
        hide.extract()
    return original_format_qa(self, unicode(soup))


def copy_arrow():
    u"""Copy the image file to the collection."""
    if not os.path.exists(
            os.path.join(mw.col.media.dir(), collection_arrow_name)):
        shutil.copy(
            os.path.join(mw.pm.addonFolder(), 'color_icons',
                         original_arrow_name), collection_arrow_name)


original_review_link_handler = Reviewer._linkHandler
Reviewer._linkHandler = review_link_handler_wrapper

original_format_qa = DataModel.formatQA
DataModel.formatQA = reduce_format_qa

addHook("mungeQA", play_button_filter)
Browser._openPreview = wrap(Browser._openPreview, add_preview_link_handler)
CardLayout.addTab = wrap(CardLayout.addTab, add_clayout_link_handler)
addHook("profileLoaded", copy_arrow)