def onAddField(self): diag = QDialog(self) form = aqt.forms.addfield.Ui_Dialog() form.setupUi(diag) fields = [f['name'] for f in self.model['flds']] form.fields.addItems(fields) form.font.setCurrentFont(QFont("Arial")) form.size.setValue(20) diag.show() # Work around a Qt bug, # https://bugreports.qt-project.org/browse/QTBUG-1894 if isMac or isWin: # No problems on Macs or Windows. form.fields.showPopup() else: # Delay showing the pop-up. self.mw.progress.timer(200, form.fields.showPopup, False) if not diag.exec_(): return if form.radioQ.isChecked(): obj = self.tform.front else: obj = self.tform.back self._addField(obj, fields[form.fields.currentIndex()], form.font.currentFont().family(), form.size.value())
def onTargetDeck(self): from aqt.tagedit import TagEdit t = self.card.template() d = QDialog(self) d.setWindowTitle("Anki") d.setMinimumWidth(400) l = QVBoxLayout() lab = QLabel(_("""\ Enter deck to place new %s cards in, or leave blank:""") % self.card.template()['name']) lab.setWordWrap(True) l.addWidget(lab) te = TagEdit(d, type=1) te.setCol(self.col) l.addWidget(te) if t['did']: te.setText(self.col.decks.get(t['did'])['name']) te.selectAll() bb = QDialogButtonBox(QDialogButtonBox.Close) bb.rejected.connect(d.close) l.addWidget(bb) d.setLayout(l) d.exec_() if not te.text().strip(): t['did'] = None else: t['did'] = self.col.decks.id(te.text())
def mousePressEvent(self, event: QMouseEvent): """ Quick hacky workaround to open Patreon link on gameOver screen click. """ if self.gameOver and self.lives == 0: openLink(ADDON.LINKS["bepatron"]) QDialog(self).mousePressEvent(event)
def downloadMedia(url, editor): # Local file : just read the file content if url.startswith("file://"): try: url = url[7:] # On windows, paths tend to be prefixed by file:/// # rather than file://, so we remove redundant slash. if re.match(r'^/[A-Za-z]:\\', url): url = url[1:] return open(url, 'rb').read() except OSError: pass app = editor.mw.app # Show download dialog d = QDialog(editor.parentWindow) d.setWindowTitle("Downloading media (0.0%)") d.setWindowModality(Qt.WindowModal) vbox = QVBoxLayout() label = QLabel(url) label.setWordWrap(True) vbox.addWidget(label) d.setLayout(vbox) d.show() # Download chunk by chunk for progress bar try: response = urllib2.urlopen(url) totSize = int(response.info().getheader('Content-Length').strip()) currentRead = 0 chunk_size = 16384 chunks = [] while True: chunk = response.read(chunk_size) currentRead += len(chunk) if not chunk: break d.setWindowTitle("Downloading media (%.1f%%)" % (currentRead * 100.0 / totSize)) app.processEvents() chunks.append(chunk) return ''.join(chunks) except urllib2.URLError: return None finally: d.close() del d
def onBrowserDisplay(self): d = QDialog() f = aqt.forms.browserdisp.Ui_Dialog() f.setupUi(d) t = self.card.template() f.qfmt.setText(t.get('bqfmt', "")) f.afmt.setText(t.get('bafmt', "")) if t.get("bfont"): f.overrideFont.setChecked(True) f.font.setCurrentFont(QFont(t.get('bfont', "Arial"))) f.fontSize.setValue(t.get('bsize', 12)) f.buttonBox.accepted.connect(lambda: self.onBrowserDisplayOk(f)) d.exec_()
def hyperlink_dialog(self): dialog = QDialog(self.parent_window) dialog.setWindowTitle("Create a hyperlink") dialog.resize(DIALOG_SIZE_X, DIALOG_SIZE_Y) ok_button_anchor = QPushButton("&OK", dialog) ok_button_anchor.setEnabled(False) ok_button_anchor.clicked.connect( lambda: self.insert_anchor(url_edit.text(), urltext_edit.text())) ok_button_anchor.clicked.connect(dialog.hide) ok_button_anchor.setAutoDefault(True) cancel_button_anchor = QPushButton("&Cancel", dialog) cancel_button_anchor.clicked.connect(dialog.hide) cancel_button_anchor.setAutoDefault(True) url_label = QLabel("Link to:") url_edit = QLineEdit() url_edit.setPlaceholderText("URL") url_edit.textChanged.connect(lambda: self.enable_ok_button( ok_button_anchor, url_edit.text(), urltext_edit.text())) urltext_label = QLabel("Text to display:") urltext_edit = QLineEdit() urltext_edit.setPlaceholderText("Text") urltext_edit.textChanged.connect(lambda: self.enable_ok_button( ok_button_anchor, url_edit.text(), urltext_edit.text())) button_box = QHBoxLayout() button_box.addStretch(1) button_box.addWidget(cancel_button_anchor) button_box.addWidget(ok_button_anchor) dialog_vbox = QVBoxLayout() dialog_vbox.addWidget(url_label) dialog_vbox.addWidget(url_edit) dialog_vbox.addWidget(urltext_label) dialog_vbox.addWidget(urltext_edit) dialog_vbox.addLayout(button_box) dialog.setLayout(dialog_vbox) # if user already selected text, put it in urltext_edit if self.selected_text: if self.selected_is_url: url_edit.setText(self.selected_text) urltext_edit.setFocus() else: urltext_edit.setText(self.selected_text) url_edit.setFocus() dialog.exec()
def getDefinitionChoiceDialog(aw, entries): d = QDialog(aw) grid = QGridLayout() # adds found definitions to dialog window for x in range(len(entries)): button = QPushButton(entries[x].word) button.clicked.connect(partial(buttonPressed, entries[x],d)) label = QLabel() label.setText(entries[x].shortDef) label.setWordWrap(True) grid.addWidget(button,x,0) grid.addWidget(label,x,1,1,5) d.setLayout(grid) return d
def __init__(self, browser): self.b = browser if not self.b.selectedNotes(): tooltip("No cards selected.") return self.d = QDialog(self.b) self.f = Ui_Dialog() self.set_up_form() self.d.setWindowModality(Qt.WindowModal) r = self.d.exec_() if not r: return self.save_history() self.b.mw.checkpoint(_("Find and Replace Tags")) self.b.model.beginReset() self.b.mw.taskman.run_in_background(self.do_find_replace, self.on_done)
def onCheckMediaDB(self): self.progress.start(immediate=True) (nohave, unused, warnings) = self.col.media.check() self.progress.finish() # generate report report = "" if warnings: report += "\n".join(warnings) + "\n" if unused: if report: report += "\n\n\n" report += _( "In media folder but not used by any cards:") report += "\n" + "\n".join(unused) if nohave: if report: report += "\n\n\n" report += _( "Used on cards but missing from media folder:") report += "\n" + "\n".join(nohave) if not report: tooltip(_("No unused or missing files found.")) return # show report and offer to delete diag = QDialog(self) diag.setWindowTitle("Anki") layout = QVBoxLayout(diag) diag.setLayout(layout) text = QTextEdit() text.setReadOnly(True) text.setPlainText(report) layout.addWidget(text) box = QDialogButtonBox(QDialogButtonBox.Close) layout.addWidget(box) if unused: b = QPushButton(_("Delete Unused Files")) b.setAutoDefault(False) box.addButton(b, QDialogButtonBox.ActionRole) b.clicked.connect( lambda c, u=unused, d=diag: self.deleteUnused(u, d)) box.rejected.connect(diag.reject) diag.setMinimumHeight(400) diag.setMinimumWidth(500) restoreGeom(diag, "checkmediadb") diag.exec_() saveGeom(diag, "checkmediadb")
def _onHtmlEdit(self, field): d = QDialog(self.widget) form = aqt.forms.edithtml.Ui_Dialog() form.setupUi(d) form.buttonBox.helpRequested.connect(lambda: openHelp("editor")) form.textEdit.setPlainText(self.note.fields[field]) form.textEdit.moveCursor(QTextCursor.End) d.exec_() html = form.textEdit.toPlainText() # filter html through beautifulsoup so we can strip out things like a # leading </div> with warnings.catch_warnings() as w: warnings.simplefilter('ignore', UserWarning) html = str(BeautifulSoup(html, "html.parser")) self.note.fields[field] = html self.note.flush() self.loadNote(focusTo=field)
def chooseList(prompt, choices, startrow=0, parent=None): if not parent: parent = aqt.mw.app.activeWindow() d = QDialog(parent) d.setWindowModality(Qt.WindowModal) l = QVBoxLayout() d.setLayout(l) t = QLabel(prompt) l.addWidget(t) c = QListWidget() c.addItems(choices) c.setCurrentRow(startrow) l.addWidget(c) bb = QDialogButtonBox(QDialogButtonBox.Ok) bb.accepted.connect(d.accept) l.addWidget(bb) d.exec_() return c.currentRow()
def onDebug(self): d = self.debugDiag = QDialog() d.silentlyClose = True frm = aqt.forms.debug.Ui_Dialog() frm.setupUi(d) font = QFontDatabase.systemFont(QFontDatabase.FixedFont) font.setPointSize(frm.text.font().pointSize() + 1) frm.text.setFont(font) frm.log.setFont(font) s = self.debugDiagShort = QShortcut(QKeySequence("ctrl+return"), d) s.activated.connect(lambda: self.onDebugRet(frm)) s = self.debugDiagShort = QShortcut( QKeySequence("ctrl+shift+return"), d) s.activated.connect(lambda: self.onDebugPrint(frm)) s = self.debugDiagShort = QShortcut(QKeySequence("ctrl+l"), d) s.activated.connect(frm.log.clear) s = self.debugDiagShort = QShortcut(QKeySequence("ctrl+shift+l"), d) s.activated.connect(frm.text.clear) d.show()
def get_id_and_pass_from_user(mw: aqt.main.AnkiQt, username="", password="") -> Tuple[str, str]: diag = QDialog(mw) diag.setWindowTitle("Anki") diag.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) # type: ignore diag.setWindowModality(Qt.WindowModal) vbox = QVBoxLayout() info_label = QLabel( without_unicode_isolation( tr(TR.SYNC_ACCOUNT_REQUIRED, link="https://ankiweb.net/account/register"))) info_label.setOpenExternalLinks(True) info_label.setWordWrap(True) vbox.addWidget(info_label) vbox.addSpacing(20) g = QGridLayout() l1 = QLabel(tr(TR.SYNC_ANKIWEB_ID_LABEL)) g.addWidget(l1, 0, 0) user = QLineEdit() user.setText(username) g.addWidget(user, 0, 1) l2 = QLabel(tr(TR.SYNC_PASSWORD_LABEL)) g.addWidget(l2, 1, 0) passwd = QLineEdit() passwd.setText(password) passwd.setEchoMode(QLineEdit.Password) g.addWidget(passwd, 1, 1) vbox.addLayout(g) bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) # type: ignore bb.button(QDialogButtonBox.Ok).setAutoDefault(True) qconnect(bb.accepted, diag.accept) qconnect(bb.rejected, diag.reject) vbox.addWidget(bb) diag.setLayout(vbox) diag.show() accepted = diag.exec_() if not accepted: return ("", "") return (user.text().strip(), passwd.text())
def get_id_and_pass_from_user(mw: aqt.main.AnkiQt, username: str = "", password: str = "") -> tuple[str, str]: diag = QDialog(mw) diag.setWindowTitle("Anki") disable_help_button(diag) diag.setWindowModality(Qt.WindowModality.WindowModal) vbox = QVBoxLayout() info_label = QLabel( without_unicode_isolation( tr.sync_account_required( link="https://ankiweb.net/account/register"))) info_label.setOpenExternalLinks(True) info_label.setWordWrap(True) vbox.addWidget(info_label) vbox.addSpacing(20) g = QGridLayout() l1 = QLabel(tr.sync_ankiweb_id_label()) g.addWidget(l1, 0, 0) user = QLineEdit() user.setText(username) g.addWidget(user, 0, 1) l2 = QLabel(tr.sync_password_label()) g.addWidget(l2, 1, 0) passwd = QLineEdit() passwd.setText(password) passwd.setEchoMode(QLineEdit.EchoMode.Password) g.addWidget(passwd, 1, 1) vbox.addLayout(g) bb = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) # type: ignore bb.button(QDialogButtonBox.StandardButton.Ok).setAutoDefault(True) qconnect(bb.accepted, diag.accept) qconnect(bb.rejected, diag.reject) vbox.addWidget(bb) diag.setLayout(vbox) diag.show() accepted = diag.exec() if not accepted: return ("", "") return (user.text().strip(), passwd.text())
def displaygrid(self, config, units): self.generate(config, units) self.win = QDialog(mw) self.wv = KanjiGridWebView() vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) vl.addWidget(self.wv) self.wv.stdHtml(self.html) hl = QHBoxLayout() vl.addLayout(hl) sh = QPushButton("Save HTML", clicked=lambda: self.savehtml(config)) hl.addWidget(sh) sp = QPushButton("Save Image", clicked=self.savepng) hl.addWidget(sp) bb = QPushButton("Close", clicked=self.win.reject) hl.addWidget(bb) self.win.setLayout(vl) self.win.resize(500, 400) self.timepoint("Window complete") return 0
def showText(txt, parent=None, type="text", run=True, geomKey=None, \ minWidth=500, minHeight=400, title="Anki", copyBtn=False): if not parent: parent = aqt.mw.app.activeWindow() or aqt.mw diag = QDialog(parent) diag.setWindowTitle(title) layout = QVBoxLayout(diag) diag.setLayout(layout) text = QTextBrowser() text.setOpenExternalLinks(True) if type == "text": text.setPlainText(txt) else: text.setHtml(txt) layout.addWidget(text) box = QDialogButtonBox(QDialogButtonBox.Close) layout.addWidget(box) if copyBtn: def onCopy(): QApplication.clipboard().setText(text.toPlainText()) btn = QPushButton(_("Copy to Clipboard")) btn.clicked.connect(onCopy) box.addButton(btn, QDialogButtonBox.ActionRole) def onReject(): if geomKey: saveGeom(diag, geomKey) QDialog.reject(diag) box.rejected.connect(onReject) def onFinish(): if geomKey: saveGeom(diag, geomKey) box.accepted.connect(onFinish) diag.setMinimumHeight(minHeight) diag.setMinimumWidth(minWidth) if geomKey: restoreGeom(diag, geomKey) if run: diag.exec_() else: return diag, box
def _getUserPass(self): d = QDialog(self.mw) d.setWindowTitle("Anki") d.setWindowModality(Qt.WindowModal) vbox = QVBoxLayout() l = QLabel( _("""\ <h1>Account Required</h1> A free account is required to keep your collection synchronized. Please \ <a href="%s">sign up</a> for an account, then \ enter your details below.""") % "https://ankiweb.net/account/login") l.setOpenExternalLinks(True) l.setWordWrap(True) vbox.addWidget(l) vbox.addSpacing(20) g = QGridLayout() l1 = QLabel(_("AnkiWeb ID:")) g.addWidget(l1, 0, 0) user = QLineEdit() g.addWidget(user, 0, 1) l2 = QLabel(_("Password:")) g.addWidget(l2, 1, 0) passwd = QLineEdit() passwd.setEchoMode(QLineEdit.Password) g.addWidget(passwd, 1, 1) vbox.addLayout(g) bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.button(QDialogButtonBox.Ok).setAutoDefault(True) bb.accepted.connect(d.accept) bb.rejected.connect(d.reject) vbox.addWidget(bb) d.setLayout(vbox) d.show() accepted = d.exec_() u = user.text() p = passwd.text() if not accepted or not u or not p: return return (u, p)
def setup(self): addonconfig = mw.addonManager.getConfig(__name__) config = types.SimpleNamespace(**addonconfig['defaults']) if addonconfig.get("_debug_time", False): self.timepoint = lambda c: print("%s: %0.3f" % (c, time.time() - self.time)) else: self.timepoint = lambda _: None config.did = mw.col.conf['curDeck'] swin = QDialog(mw) vl = QVBoxLayout() fl = QHBoxLayout() deckcb = QComboBox() deckcb.addItems(sorted(mw.col.decks.allNames())) deckcb.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) fl.addWidget(QLabel("Deck: ")) deckcb.setCurrentText(mw.col.decks.get(config.did)['name']) def change_did(deckname): config.did = mw.col.decks.byName(deckname)['id'] deckcb.currentTextChanged.connect(change_did) fl.addWidget(deckcb) vl.addLayout(fl) frm = QGroupBox("Settings") vl.addWidget(frm) il = QVBoxLayout() fl = QHBoxLayout() field = QLineEdit() field.setPlaceholderText( "e.g. \"kanji\", \"hanzi\" or \"sentence-kanji\" (default: \"%s\")" % config.pattern) il.addWidget( QLabel("Pattern or Field names to search for (case insensitive):")) fl.addWidget(field) liter = QCheckBox("Match exactly") liter.setChecked(config.literal) fl.addWidget(liter) il.addLayout(fl) stint = QSpinBox() stint.setRange(1, 65536) stint.setValue(config.interval) il.addWidget(QLabel("Card interval considered strong:")) il.addWidget(stint) ttcol = QSpinBox() ttcol.setRange(1, 99) ttcol.setValue(config.thin) il.addWidget(QLabel("Number of Columns in the in-app table:")) il.addWidget(ttcol) wtcol = QSpinBox() wtcol.setRange(1, 99) wtcol.setValue(config.wide) il.addWidget(QLabel("Number of Columns in the exported table:")) il.addWidget(wtcol) groupby = QComboBox() groupby.addItems([ *("None, sorted by " + x.pretty_value() for x in SortOrder), *(x.name for x in data.groups), ]) groupby.setCurrentIndex(config.groupby) il.addWidget(QLabel("Group by:")) il.addWidget(groupby) shnew = QCheckBox("Show units not yet seen") shnew.setChecked(config.unseen) il.addWidget(shnew) toolt = QCheckBox("Show informational tooltips") toolt.setChecked(config.tooltips) il.addWidget(toolt) frm.setLayout(il) hl = QHBoxLayout() vl.addLayout(hl) gen = QPushButton("Generate", clicked=swin.accept) hl.addWidget(gen) cls = QPushButton("Close", clicked=swin.reject) hl.addWidget(cls) swin.setLayout(vl) swin.setTabOrder(gen, cls) swin.setTabOrder(cls, field) swin.setTabOrder(field, liter) swin.setTabOrder(liter, stint) swin.setTabOrder(stint, ttcol) swin.setTabOrder(ttcol, wtcol) swin.setTabOrder(wtcol, groupby) swin.setTabOrder(groupby, shnew) swin.setTabOrder(shnew, toolt) swin.resize(500, 400) if swin.exec_(): mw.progress.start(immediate=True) if len(field.text().strip()) != 0: config.pattern = field.text().lower() config.pattern = config.pattern.split() config.literal = liter.isChecked() config.interval = stint.value() config.thin = ttcol.value() config.wide = wtcol.value() config.groupby = groupby.currentIndex() config.unseen = shnew.isChecked() config.tooltips = toolt.isChecked() self.makegrid(config) mw.progress.finish() self.win.show()
def create_link(editor): dialog = QDialog(editor.parentWindow, Qt.Dialog) form = link.Ui_Dialog() form.setupUi(dialog) # Default values # Line of text form.line_display.setText(editor.web.selectedText()) # open form.combo_open_in.setCurrentIndex({ "Browser": 0, "Previewer": 1 }.get(getUserOption("Last open in", "Browser"), 0)) # search form.combo_search_type.setCurrentIndex({ "Note": 0, "Card": 1, "Query": 2 }.get(getUserOption("Last search type", "Note"), 0)) # query def default() -> str: search_type = ["Note", "Card", "Query"][form.combo_search_type.currentIndex()] if search_type == "Note": if editor.note: return str(editor.note.id) elif search_type == "Card": if editor.card: return str(editor.card.id) elif editor.note: cards = editor.note.cards() if cards: return str(cards[0].id) else: return getUserOption("Last query", "") return "" def set_default() -> None: form.line_search.setText(default()) set_default() form.button_current.clicked.connect(set_default) ## dialog.exec() mw.setupDialogGC(dialog) # Get values # Line of text text = form.line_display.text() setUserOption("Last open in", text) # open open_in = ["Browser search", "Previewer"][form.combo_open_in.currentIndex()] setUserOption("Last open in", open_in) # search search_type = ["Note", "Card", "Query"][form.combo_search_type.currentIndex()] setUserOption("Last search type", search_type) # query query = form.line_search.text() setUserOption("Last query", query) # Replace text if search_type == "Note": query = f"nid:{query}" elif search_type == "Card": query = f"cid:{query}" text = f"""<a onclick="pycmd('{open_in}:{query}')">{text}</a>""" editor.web.eval( f"document.execCommand('insertHTML', false, {json.dumps(text)});")