def setupBrowserShortcuts(self): # self is browser cut = gc("shortcut: open window") if cut: cm = QShortcut(QKeySequence(cut), self) qconnect(cm.activated, lambda b=self: open_multiline_searchwindow(b)) view = getMenu(self, "&View") action = QAction(self) action.setText("Show search string in multi-line dialog") view.addAction(action) action.triggered.connect(lambda _, b=self: open_multiline_searchwindow(b))
def mainSetupMenus(): global alreadyrun if alreadyrun: return alreadyrun = True view = getMenu(mw, "More &Stats") action = QAction(mw) action.setText("New Cards processed today") view.addAction(action) action.triggered.connect(show_new_cards_learned)
def main_setup_menus(): # noqa global alreadyrun if alreadyrun: return alreadyrun = True view = get_menu(mw, "&View") action = QAction(mw) action.setText("Card Stats") action.setCheckable(True) action.setChecked(sidebar_visibility) action.setShortcut(QKeySequence("Shift+C")) view.addAction(action) action.toggled.connect(card_stats)
from anki.hooks import addHook from .rule import updateAll from aqt.qt import QAction from aqt import mw action = QAction(mw) action.setText("Apply trigger->action rules") mw.form.menuTools.addAction(action) action.triggered.connect(updateAll)
def create_menu(): mn = QMenu() mn.setTitle("Nachschlagen") mw.form.menuTools.addAction(mn.menuAction()) # mw.form.menu_nachschlagen = mn # add actions if show_japanese: # Maybe not show the Japanese actions. wae = QAction(mw) wae.setText("Japanisch bei Wadoku") # wae.setShortcut("Ctrl+4") mn.addAction(wae) mw.connect(wae, SIGNAL("triggered()"), on_lookup_wadoku_expression) wam = QAction(mw) wam.setText("Deutsch bei Wadoku") # wam.setShortcut("Ctrl+2") mn.addAction(wam) mw.connect(wam, SIGNAL("triggered()"), on_lookup_wadoku_meaning) was = QAction(mw) was.setText("Auswahl bei Wadoku") mn.addAction(was) mw.connect(was, SIGNAL("triggered()"), on_lookup_wadoku_selection) if show_saiga: # Personal taste: i like the Kanjilexikon better than the # Saiga look up. So i like this switched off. sae = QAction(mw) sae.setText("Kanji bei Saiga") #sae.setShortcut("Ctrl+4") mn.addAction(sae) mw.connect(sae, SIGNAL("triggered()"), on_lookup_saiga_expression) sas = QAction(mw) sas.setText("Kanjiauswahl bei Saiga") mn.addAction(sas) mw.connect(sas, SIGNAL("triggered()"), on_lookup_saiga_selection) kle = QAction(mw) kle.setText("Kanji bei Kanji-Lexikon") # kle.setShortcut("Ctrl+4") mn.addAction(kle) mw.connect(kle, SIGNAL("triggered()"), on_lookup_kl_expression) kls = QAction(mw) kls.setText("Kanjiauswahl bei Kanji-Lexikon") mn.addAction(kls) mw.connect(kls, SIGNAL("triggered()"), on_lookup_kl_selection) # Show these always. fae = QAction(mw) fae.setText("Ausdruck bei Forvo") # fae.setShortcut("Ctrl+4") mn.addAction(fae) mw.connect(fae, SIGNAL("triggered()"), on_lookup_forvo_expression) fas = QAction(mw) fas.setText("Auswahl bei Forvo") mn.addAction(fas) mw.connect(fas, SIGNAL("triggered()"), on_lookup_forvo_selection)
if unicodedata.category(c) == "Nd": return True return False def open_dialog_in_editor(editor: Editor): selected = editor.web.selectedText() open_dialog(editor.widget, selected, not contains_digit(selected)) def on_editor_did_init_buttons(buttons: List[str], editor: Editor): global config # pylint: disable=global-statement btn = editor.addButton( icon=os.path.join(addon_dir, "icon.svg"), cmd="armajor", func=open_dialog_in_editor, tip="مولد نظام المذكرات الصوتي للعربية", keys=config.get("shortcut", "Ctrl+Shift+K"), ) buttons.append(btn) if aqt.mw: action = QAction(aqt.mw) action.setText("مولد نظام المذكرات الصوتي للعربية") aqt.mw.form.menuTools.addAction(action) action.triggered.connect(lambda: open_dialog(aqt.mw)) # type: ignore config = aqt.mw.addonManager.getConfig(__name__) gui_hooks.editor_did_init_buttons.append(on_editor_did_init_buttons)
] ] def run(actions): if isinstance(actions, str): actions = [actions] for action in actions: for data in datas: if considerTable(data.name): getattr(data, action)() tooltip(f"Ended {action}") action = QAction(mw) action.setText("Anki to Readable") mw.form.menuTools.addAction(action) action.triggered.connect(lambda: run([ "clarify" #,"view" ])) action.setShortcut(QKeySequence("Ctrl+Shift+C")) action = QAction(mw) action.setText("Readable to anki") mw.form.menuTools.addAction(action) action.setShortcut(QKeySequence("Ctrl+Shift+R")) action.triggered.connect(lambda: run(["rebuild"] + ([] if keepTable() else ["delete"]))) action = QAction(mw)
imp = 0 noCard = 0 for line in lines: ret = addBackNote(line, wrongMids, presentNids) if ret is True or ret == "no card": imp += 1 if ret == "no card": noCard += 1 cnt += 1 if (cnt % 100) == 0: print(f"Saving the {cnt} first elements") if wrongMids: message.append(f"The wrong mids are {wrongMids}") if presentNids: message.append(f"Already contains note with nids {presentNids}") if imp: message.append(f"Succesfully imported back {imp} notes") else: message.append(f"No note imported") if noCard: message.append( f"{noCard} notes have generated 0 card. We added card 1 to them, and the tag NoteWithNoCard. You should edit them quickly, or «empty cards» will make them disappear." ) showInfo("\n".join(message)) action = QAction(mw) action.setText("add back") mw.form.menuTools.addAction(action) action.triggered.connect(addBack)
if model is not None: return model = mm.new(lpcg_models.NAME) for i in lpcg_models.FIELDS: field = mm.newField(i) mm.addField(model, field) t = mm.newTemplate(lpcg_models.TEMPLATE_NAME) t['qfmt'] = lpcg_models.FRONT_TEMPLATE t['afmt'] = lpcg_models.BACK_TEMPLATE mm.addTemplate(model, t) model['css'] = lpcg_models.STYLING model['sortf'] = lpcg_models.SORT_FIELD mm.add(model) def open_dialog(): "Launch the add-poem dialog." dialog = LPCGDialog(aqt.mw) dialog.exec_() action = QAction(aqt.mw) action.setText("Import &Lyrics/Poetry") aqt.mw.form.menuTools.addAction(action) action.triggered.connect(open_dialog) addHook('profileLoaded', ensure_note_type) # TODO: bug of unclear source with both end markers? only happens sometimes. I # added a 'continue' which may fix this but seems unlikely because it's the # wrong order.
def create_menu(): u"""Set up the menu.""" mn = QMenu() mn.setTitle("Nachschlagen") mw.form.menuTools.addAction(mn.menuAction()) # mw.form.menu_nachschlagen = mn # add actions if show_japanese: # Maybe not show the Japanese actions. wae = QAction(mw) wae.setText("Japanisch bei Wadoku") # wae.setShortcut("Ctrl+4") mn.addAction(wae) mw.connect(wae, SIGNAL("triggered()"), on_lookup_wadoku_expression) wam = QAction(mw) wam.setText("Deutsch bei Wadoku") # wam.setShortcut("Ctrl+2") mn.addAction(wam) mw.connect(wam, SIGNAL("triggered()"), on_lookup_wadoku_meaning) was = QAction(mw) was.setText("Auswahl bei Wadoku") mn.addAction(was) mw.connect(was, SIGNAL("triggered()"), on_lookup_wadoku_selection) if show_saiga: # Personal taste: i like the Kanjilexikon better than the # Saiga look up. So i like this switched off. sae = QAction(mw) sae.setText("Kanji bei Saiga") #sae.setShortcut("Ctrl+4") mn.addAction(sae) mw.connect(sae, SIGNAL("triggered()"), on_lookup_saiga_expression) sas = QAction(mw) sas.setText("Kanjiauswahl bei Saiga") mn.addAction(sas) mw.connect(sas, SIGNAL("triggered()"), on_lookup_saiga_selection) kle = QAction(mw) kle.setText("Kanji bei Kanji-Lexikon") # kle.setShortcut("Ctrl+4") mn.addAction(kle) mw.connect(kle, SIGNAL("triggered()"), on_lookup_kl_expression) kls = QAction(mw) kls.setText("Kanjiauswahl bei Kanji-Lexikon") mn.addAction(kls) mw.connect(kls, SIGNAL("triggered()"), on_lookup_kl_selection) # Show these always. fae = QAction(mw) fae.setText("Ausdruck bei Forvo") # fae.setShortcut("Ctrl+4") mn.addAction(fae) mw.connect(fae, SIGNAL("triggered()"), on_lookup_forvo_expression) fas = QAction(mw) fas.setText("Auswahl bei Forvo") mn.addAction(fas) mw.connect(fas, SIGNAL("triggered()"), on_lookup_forvo_selection)
from anki.lang import _ from aqt.qt import QAction, QKeySequence def ensure(): mw.checkpoint("Unique GUID") lastGuid = None nids = [] lastNid = None for guid, nid in mw.col.db.all("select guid, id from notes order by guid, id"): if lastGuid == guid: mw.col.modSchema(True) mw.col.db.execute( "update notes set guid = ? where id = ? ", guid64(), nid) nids.append((nid, lastNid)) lastGuid = guid lastNid = nid if nids: s = _("The guid of the following notes have been changed:") s += "\n".join(_("Note %d which was a copy of note %d") % (nid, lastNid) for nid, lastNid in nids) showWarning(s) else: tooltip(_("Each guid was unique. No correction required")) action = QAction(mw) action.setText("Ensure unique GUID") mw.form.menuTools.addAction(action) action.triggered.connect(ensure)
import anki from aqt.deckbrowser import DeckBrowser from .gui.configurator import Configurator from .gui.kanjigrid import KanjiGrid from .gui.launcher import Launcher from aqt import mw from aqt.qt import QAction mw.kanjigrid = { 'configure': Configurator(mw), 'kanjigrid': KanjiGrid(mw), 'launcher': Launcher(mw), } def preload(a, b): mw.kanjigrid['configure'].deck_widget() mw.kanjigrid['configure'].note_widget() DeckBrowser._renderPage = anki.hooks.wrap(DeckBrowser._renderPage, preload, 'after') launch_action = QAction(mw) launch_action.setText("Generate Kanji Grid") mw.form.menuTools.addAction(launch_action) launch_action.triggered.connect(mw.kanjigrid['launcher'].show)
# -*- mode: python ; coding: utf-8 -*- # Copyright © 2012 Roland Sieker # This file: License: GNU GPL, version 3 or later; # http://www.gnu.org/copyleft/gpl.html # """Change the names of files to more readable versions. Go through the collection and detect files that alook like MD5 hashes used by Anki <1.2, look at the note for a better name and rename the files, changing the notes as well. """ import dehashilator from aqt import mw from aqt.qt import QAction, SIGNAL from dehashilator import __version__ dhma = QAction(mw) dhma.setText("Dehashilate media") mw.form.menuTools.addAction(dhma) mw.connect(dhma, SIGNAL("triggered()"), dehashilator.test_and_dehashilate)
def init_menu_option(): action = QAction(mw) action.setText("Custom Styles Options...") mw.form.menuTools.addAction(action) action.triggered.connect(on_settings)
from aqt import mw from aqt.qt import QAction from .init import * action = QAction(mw) action.setText("All fields searchable") mw.form.menuTools.addAction(action) action.triggered.connect(lambda: applyAllNote(allSearch)) action = QAction(mw) action.setText("Normal search") mw.form.menuTools.addAction(action) action.triggered.connect(lambda: applyAllNote(normalSearch))
# This hook isn't in some supported versions of Anki yet, # so silently skip adding the warning if it's not available. # After we drop support for 2.1.48 and below, we can remove this check. if hasattr(aqt.gui_hooks, 'add_cards_did_change_note_type'): # lol at the line being too long because of the false positive lint # pylint: disable=no-member, line-too-long aqt.gui_hooks.add_cards_did_change_note_type.append( on_change_note_type) # type: ignore aqt.gui_hooks.add_cards_did_init.append(on_add_init) if aqt.mw is not None: # Set up menu option to begin a sync. action = QAction(aqt.mw) action.setText("Sync from &TiddlyWiki") action.setShortcut(QKeySequence("Shift+Y")) aqt.mw.form.menuTools.addAction(action) action.triggered.connect(begin_sync) # type: ignore # Set up config dialog. aqt.mw.addonManager.setConfigAction(__name__, edit_settings) # Set up reminder message when user selects the TR note type to add notes. register_note_type_warning() # Set up macro exporter. def add_exporter(lst): lst.append(MACRO_EXPORTER_PROPERTIES) anki.hooks.exporters_list_created.append(add_exporter)
from aqt import mw from aqt.qt import QAction CARD_NEW = 0 NEW_CARDS_RANDOM = 0 def redue(): col = mw.col sched = col.sched cids = mw.col.db.list(f"select id from cards where type = {CARD_NEW} and due > 1000000 order by id") sched.sortCards(cids) col.conf['nextPos'] = col.db.scalar( f"select max(due)+1 from cards where type = {CARD_NEW}") or 0 dconfs = col.decks.dconf random_dconfs = [dconf for dconf in dconfs.values() if dconf["new"]['order'] == NEW_CARDS_RANDOM] for dconf in random_dconfs: sched.resortConf(dconf) action = QAction(mw) action.setText("Clean due") mw.form.menuTools.addAction(action) action.triggered.connect(redue)
mw.progress.finish() mw.col.reset() mw.reset() tooltip(_("""Delay changed.""")) def runMain(): decreaseDelay(getReviewCards()) def runBrowser(browser): cids = browser.selectedCards() decreaseDelay(cids) text = _("Shorten card delays") def setupBrowserMenu(browser): a = QAction(text, browser) a.triggered.connect(lambda: runBrowser(browser)) browser.form.menuEdit.addAction(a) addHook("browser.setupMenus", setupBrowserMenu) action = QAction(mw) action.setText(text) mw.form.menuTools.addAction(action) action.triggered.connect(runMain)
mm = aqt.mw.col.models model = mm.byName(lpcg_models.NAME) if model is not None: return model = mm.new(lpcg_models.NAME) for i in lpcg_models.FIELDS: field = mm.newField(i) mm.addField(model, field) t = mm.newTemplate(lpcg_models.TEMPLATE_NAME) t['qfmt'] = lpcg_models.FRONT_TEMPLATE t['afmt'] = lpcg_models.BACK_TEMPLATE mm.addTemplate(model, t) model['css'] = lpcg_models.STYLING model['sortf'] = lpcg_models.SORT_FIELD mm.add(model) def open_dialog(): "Launch the add-poem dialog." dialog = LPCGDialog(aqt.mw) dialog.exec_() action = QAction(aqt.mw) action.setText("Import &Lyrics/Poetry") aqt.mw.form.menuTools.addAction(action) action.triggered.connect(open_dialog) addHook('profileLoaded', ensure_note_type)
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. ############################################################################### import time import anki.collection import aqt from aqt import mw from aqt.qt import QAction # overwrite autosave function with one that triggers faster and can be forced SAVE_THRESHOLD = mw.addonManager.getConfig(__name__)['saveEveryNSeconds'] def newAutosave(self, force=False): if force or time.time() - self._lastSave > SAVE_THRESHOLD: self.save() return True anki.collection._Collection.autosave = newAutosave # install new menu item to force a save action = QAction(mw) action.setText("Save now") action.setShortcut("Ctrl+S") mw.form.menuCol.addAction(action) action.triggered.connect(lambda: mw.col.autosave(True))
# may have customized orders in the due field. customSortCards(col, str_dids, start=redline, shuffle=shuffle) # Reset pos counter col.conf['nextPos'] = col.db.scalar( "select max(due)+1 from cards where type = 0") or 0 mw.progress.finish() if AUTOMATIC_SCAN_BEFORE_DB_CHECKUP: anki.collection._Collection.fixIntegrity = wrap( anki.collection._Collection.fixIntegrity, redue, "before") else: action = QAction(mw) action.setText("Clean bulky dues") mw.form.menuTools.addAction(action) action.triggered.connect(lambda: redue(mw.col)) ############################################ ## UTILS.py ########################################### def customSortCards(col, str_dids, start=1, shuffle=False): now = intTime() if start <= 65536: #16bits limit = "and due>666000 " due = start else: #reserve the top 0-10k for user custom dues
# accompanied this program. # # If not, please request a copy through one of the means of contact # listed here: <https://glutanimate.com/contact/>. # # Any modifications to this file must keep this entire header intact. """ Initializes add-on components. """ import aqt from aqt import mw from aqt.qt import QAction from . import browser, editor from .conf_dialog import MyConfigWindow from .config import getUserOption aqt.dialogs.register_dialog("html_cleaner_config", MyConfigWindow, None) def onAdjustSettings(): aqt.dialogs.open("html_cleaner_config", mw) if getUserOption("config_window_show_experimental_config_window"): action = QAction(mw) action.setText("Html Cleaner: Adjust Clean settings") mw.form.menuTools.addAction(action) action.triggered.connect(onAdjustSettings)