def setupMainWindow(self): # main window self.form = aqt.forms.main.Ui_MainWindow() self.form.setupUi(self) # toolbar tweb = self.toolbarWeb = aqt.webview.AnkiWebView() tweb.title = "top toolbar" tweb.setFocusPolicy(Qt.WheelFocus) self.toolbar = aqt.toolbar.Toolbar(self, tweb) self.toolbar.draw() # main area self.web = aqt.webview.AnkiWebView() self.web.title = "main webview" self.web.setFocusPolicy(Qt.WheelFocus) self.web.setMinimumWidth(400) # bottom area sweb = self.bottomWeb = aqt.webview.AnkiWebView() sweb.title = "bottom toolbar" sweb.setFocusPolicy(Qt.WheelFocus) # add in a layout self.mainLayout = QVBoxLayout() self.mainLayout.setContentsMargins(0,0,0,0) self.mainLayout.setSpacing(0) self.mainLayout.addWidget(tweb) self.mainLayout.addWidget(self.web) self.mainLayout.addWidget(sweb) self.form.centralwidget.setLayout(self.mainLayout) # force webengine processes to load before cwd is changed if isWin: for o in self.web, self.bottomWeb: o.requiresCol = False o._domReady = False o._page.setContent(bytes("", "ascii"))
def _create_gui(self): self.setWindowTitle(tr(TR.ACTIONS_PREVIEW)) qconnect(self.finished, self._on_finished) self.silentlyClose = True self.vbox = QVBoxLayout() self.vbox.setContentsMargins(0, 0, 0, 0) self._web = AnkiWebView(title="previewer") self.vbox.addWidget(self._web) self.bbox = QDialogButtonBox() self._replay = self.bbox.addButton(tr(TR.ACTIONS_REPLAY_AUDIO), QDialogButtonBox.ActionRole) self._replay.setAutoDefault(False) self._replay.setShortcut(QKeySequence("R")) self._replay.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="R")) qconnect(self._replay.clicked, self._on_replay_audio) both_sides_button = QCheckBox(tr(TR.QT_MISC_BACK_SIDE_ONLY)) both_sides_button.setShortcut(QKeySequence("B")) both_sides_button.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="B")) self.bbox.addButton(both_sides_button, QDialogButtonBox.ActionRole) self._show_both_sides = self.mw.col.conf.get("previewBothSides", False) both_sides_button.setChecked(self._show_both_sides) qconnect(both_sides_button.toggled, self._on_show_both_sides) self.vbox.addWidget(self.bbox) self.setLayout(self.vbox) restoreGeom(self, "preview")
def _create_gui(self): self.setWindowTitle(_("Preview")) qconnect(self.finished, self._on_finished) self.silentlyClose = True self.vbox = QVBoxLayout() self.vbox.setContentsMargins(0, 0, 0, 0) self._web = AnkiWebView(title="previewer") self.vbox.addWidget(self._web) self.bbox = QDialogButtonBox() self._replay = self.bbox.addButton(_("Replay Audio"), QDialogButtonBox.ActionRole) self._replay.setAutoDefault(False) self._replay.setShortcut(QKeySequence("R")) self._replay.setToolTip(_("Shortcut key: %s" % "R")) qconnect(self._replay.clicked, self._on_replay_audio) both_sides_button = QCheckBox(_("Show Both Sides")) both_sides_button.setShortcut(QKeySequence("B")) both_sides_button.setToolTip(_("Shortcut key: %s" % "B")) self.bbox.addButton(both_sides_button, QDialogButtonBox.ActionRole) self._show_both_sides = self.mw.col.conf.get("previewBothSides", False) both_sides_button.setChecked(self._show_both_sides) qconnect(both_sides_button.toggled, self._on_show_both_sides) self.vbox.addWidget(self.bbox) self.setLayout(self.vbox) restoreGeom(self, "preview")
def _create_gui(self) -> None: self.setWindowTitle(tr.actions_preview()) self.close_shortcut = QShortcut(QKeySequence("Ctrl+Shift+P"), self) qconnect(self.close_shortcut.activated, self.close) qconnect(self.finished, self._on_finished) self.silentlyClose = True self.vbox = QVBoxLayout() self.vbox.setContentsMargins(0, 0, 0, 0) self._web = AnkiWebView(title="previewer") self.vbox.addWidget(self._web) self.bbox = QDialogButtonBox() self._replay = self.bbox.addButton( tr.actions_replay_audio(), QDialogButtonBox.ButtonRole.ActionRole) self._replay.setAutoDefault(False) self._replay.setShortcut(QKeySequence("R")) self._replay.setToolTip(tr.actions_shortcut_key(val="R")) qconnect(self._replay.clicked, self._on_replay_audio) both_sides_button = QCheckBox(tr.qt_misc_back_side_only()) both_sides_button.setShortcut(QKeySequence("B")) both_sides_button.setToolTip(tr.actions_shortcut_key(val="B")) self.bbox.addButton(both_sides_button, QDialogButtonBox.ButtonRole.ActionRole) self._show_both_sides = self.mw.col.get_config_bool( Config.Bool.PREVIEW_BOTH_SIDES) both_sides_button.setChecked(self._show_both_sides) qconnect(both_sides_button.toggled, self._on_show_both_sides) self.vbox.addWidget(self.bbox) self.setLayout(self.vbox) restoreGeom(self, "preview")
def setupMappingFrame(self): # qt seems to have a bug with adding/removing from a grid, so we add # to a separate object and add/remove that instead self.frame = QFrame(self.frm.mappingArea) self.frm.mappingArea.setWidget(self.frame) self.mapbox = QVBoxLayout(self.frame) self.mapbox.setContentsMargins(0, 0, 0, 0) self.mapwidget = None
def _setupUI(self): """Basic UI setup""" mainLayout = QVBoxLayout() self.label = QLabel("Please press the key combination\n" "you would like to assign") self.label.setAlignment(Qt.AlignCenter) mainLayout.addWidget(self.label) self.setLayout(mainLayout) self.setWindowTitle("Grab key combination")
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 __init__(self, editor, parent_window, selected_text, selected_is_url=False): QDialog.__init__(self, parent_window, Qt.Window) self.editor_instance = editor self.parent_window = parent_window self.selected_text = selected_text self.selected_is_url = selected_is_url self.setWindowTitle("Anki: Create a hyperlink") self.resize(DIALOG_SIZE_X, DIALOG_SIZE_Y) restoreGeom(self, "318752047__add_hyperlink") self.pb_ok = QPushButton("&OK", self) self.pb_ok.setEnabled(False) self.pb_ok.clicked.connect( lambda: self.insert_anchor(url_edit.text(), urltext_edit.text())) self.pb_cancel = QPushButton("&Cancel", self) self.pb_cancel.clicked.connect(self.reject) url_label = QLabel("Link to:") url_edit = QLineEdit() url_edit.setPlaceholderText("URL") url_edit.textChanged.connect(lambda: self.enable_ok_button( self.pb_ok, 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( self.pb_ok, url_edit.text(), urltext_edit.text())) self.button_bar = QHBoxLayout() self.button_bar.addStretch(1) self.button_bar.addWidget(self.pb_cancel) self.button_bar.addWidget(self.pb_ok) self.dialog_vbox = QVBoxLayout() self.dialog_vbox.addWidget(url_label) self.dialog_vbox.addWidget(url_edit) self.dialog_vbox.addWidget(urltext_label) self.dialog_vbox.addWidget(urltext_edit) self.dialog_vbox.addLayout(self.button_bar) self.setLayout(self.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()
def _setup_ui(self): self.setWindowTitle(self.title) self.setMinimumWidth(600) self.setMinimumHeight(400) vbox = QVBoxLayout() vbox.addLayout(self._ui_top_row()) vbox.addLayout(self._ui_field_select_row()) vbox.addWidget(self._ui_log()) vbox.addLayout(self._ui_bottom_row()) self.setLayout(vbox)
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 __init__(self, parent, question, help=None, edit=None, default="", \ title="Anki", minWidth=400): QDialog.__init__(self, parent) self.setWindowTitle(title) self.question = question self.help = help self.qlabel = QLabel(question) self.setMinimumWidth(minWidth) v = QVBoxLayout() v.addWidget(self.qlabel) if not edit: edit = QLineEdit() self.l = edit if default: self.l.setText(default) self.l.selectAll() v.addWidget(self.l) buts = QDialogButtonBox.Ok | QDialogButtonBox.Cancel if help: buts |= QDialogButtonBox.Help b = QDialogButtonBox(buts) v.addWidget(b) self.setLayout(v) b.button(QDialogButtonBox.Ok).clicked.connect(self.accept) b.button(QDialogButtonBox.Cancel).clicked.connect(self.reject) if help: b.button(QDialogButtonBox.Help).clicked.connect(self.helpRequested)
def initUI(self): vlay = QVBoxLayout() self.input_line = PanelInputLine() self.list_box = QListWidget() for i in range(self.max_items): self.list_box.insertItem(i, '') vlay.addWidget(self.input_line) vlay.addWidget(self.list_box) self.buttonbox = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) vlay.addWidget(self.buttonbox) # self.buttonbox.accepted.disconnect(self.accept) # leads to: TypeError: disconnect() failed between 'accepted' and 'accept' self.buttonbox.accepted.connect(self.accept) self.buttonbox.rejected.connect(self.reject) self.update_listbox() self.setLayout(vlay) self.resize(800, 350) restoreGeom(self, "TT/TIFP") self.list_box.setAlternatingRowColors(True) # connections self.input_line.im_changed.connect(self.text_changed) self.input_line.textChanged.connect(self.text_changed) self.input_line.returnPressed.connect(self.return_pressed) self.input_line.down_pressed.connect(self.down_pressed) self.input_line.up_pressed.connect(self.up_pressed) self.list_box.itemDoubleClicked.connect(self.item_doubleclicked) self.list_box.installEventFilter(self) self.input_line.setFocus()
def show_text_entry_window(self): """ Show the first window of the utility. This window prompts the user to paste in some text. """ self.text_entry_window = w = QWidget(mw, flags=QtCore.Qt.Window) w.setWindowTitle(" Prestudy") vbox = QVBoxLayout() vbox.addWidget(QLabel("Paste in the text you want to read:")) self.input_text_box = QTextEdit() vbox.addWidget(self.input_text_box) continue_button = QPushButton("Continue") # TODO not sure why a lambda is needed here continue_button.clicked.connect( lambda: self.text_entry_continue_action()) hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(continue_button) vbox.addLayout(hbox) w.setLayout(vbox) w.show()
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 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 __init__(self, parent, bodyhtml, jsSavecommand, wintitle, dialogname): super(ExtraWysiwygEditorForField, self).__init__(parent) self.jsSavecommand = jsSavecommand self.parent = parent self.setWindowTitle(wintitle) self.resize(810, 700) restoreGeom(self, "805891399_winsize") mainLayout = QVBoxLayout() mainLayout.setContentsMargins(0, 0, 0, 0) mainLayout.setSpacing(0) self.setLayout(mainLayout) self.web = MyWebView(self) # maybe also self.parent? self.web.allowDrops = True # default in webview/AnkiWebView is False self.web.title = dialogname self.web.contextMenuEvent = self.contextMenuEvent mainLayout.addWidget(self.web) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Save) mainLayout.addWidget(self.buttonBox) self.buttonBox.accepted.connect(self.onAccept) self.buttonBox.rejected.connect(self.onReject) QMetaObject.connectSlotsByName(self) acceptShortcut = QShortcut(QKeySequence("Ctrl+Return"), self) acceptShortcut.activated.connect(self.onAccept) zoomIn_Shortcut = QShortcut(QKeySequence("Ctrl++"), self) zoomIn_Shortcut.activated.connect(self.web.zoom_in) zoomOut_Shortcut = QShortcut(QKeySequence("Ctrl+-"), self) zoomOut_Shortcut.activated.connect(self.web.zoom_out) self.web.stdHtml(body=bodyhtml, css=cssfiles, js=addon_jsfiles + other_jsfiles, head="", context=self)
def _setup_ui(self): self.setWindowTitle("View Log") self.setMinimumWidth(600) self.setMinimumHeight(400) vbox = QVBoxLayout() vbox.addLayout(self._ui_top_row()) vbox.addWidget(self._ui_log()) vbox.addLayout(self._ui_bottom_row()) self.setLayout(vbox) self.fillLog()
def updateWindow(self, html): if html is None: return False # build view webview = AnkiWebView() webview.stdHtml(html) # Clear old layout if self.__layout: QObjectCleanupHandler().add(self.__layout) # build layout self.__layout = QVBoxLayout() self.__layout.setContentsMargins(0, 0, 0, 0) self.__layout.addWidget(webview) # Update window self.setLayout(self.__layout) self.update()
def _setupUi(self): flabel = QLabel("In this field:") self.fsel = QComboBox() fields = self._getFields() self.fsel.addItems(fields) self.cb = QCheckBox() self.cb.setText("transform to plain text") f_hbox = QHBoxLayout() f_hbox.addWidget(flabel) f_hbox.addWidget(self.fsel) f_hbox.addWidget(self.cb) f_hbox.setAlignment(Qt.AlignLeft) button_box = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, orientation=Qt.Horizontal, parent=self, ) bottom_hbox = QHBoxLayout() bottom_hbox.addWidget(button_box) vbox_main = QVBoxLayout() vbox_main.addLayout(f_hbox) vbox_main.addLayout(bottom_hbox) self.setLayout(vbox_main) self.setWindowTitle("Batch Clean Selected Notes") button_box.rejected.connect(self.reject) button_box.accepted.connect(self.accept) self.rejected.connect(self.reject) self.accepted.connect(self.accept) self.fsel.setFocus()
def __init__(self, mw, note, ord=0, parent=None, addMode=False): QDialog.__init__(self, parent or mw, Qt.Window) mw.setupDialogGC(self) self.mw = aqt.mw self.parent = parent or mw self.note = note self.ord = ord self.col = self.mw.col self.mm = self.mw.col.models self.model = note.model() self.mw.checkpoint(_("Card Types")) self.addMode = addMode if addMode: # save it to DB temporarily self.emptyFields = [] for name, val in list(note.items()): if val.strip(): continue self.emptyFields.append(name) note[name] = "(%s)" % name note.flush() self.setupTopArea() self.setupMainArea() self.setupButtons() self.setupShortcuts() self.setWindowTitle(_("Card Types for %s") % self.model['name']) v1 = QVBoxLayout() v1.addWidget(self.topArea) v1.addWidget(self.mainArea) v1.addLayout(self.buttons) v1.setContentsMargins(12,12,12,12) self.setLayout(v1) self.redraw() restoreGeom(self, "CardLayout") self.setWindowModality(Qt.ApplicationModal) self.show() # take the focus away from the first input area when starting up, # as users tend to accidentally type into the template self.setFocus()
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 gen_qt_hr(): vbox = QVBoxLayout() hr = QFrame() hr.setAutoFillBackground(True) hr.setFrameShape(QFrame.HLine) hr.setStyleSheet("QFrame { background-color: #0060bf; color: #0060bf; }") hr.setFixedHeight(2) vbox.addWidget(hr) vbox.addSpacing(4) return vbox
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 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 _setupUI(self): vbox = QVBoxLayout() self.setLayout(vbox) self.lemmaLineEdit = LemmaLineEdit() vbox.addWidget(self.lemmaLineEdit) self.lemmaLineEdit.newLemmas.connect(self.setLemmas) self.ankiwordListWidget = AnkiwordListWidget( ankiInterface=self.ankiInterface) vbox.addWidget(self.ankiwordListWidget) self.show()
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 setup_reward_tab(dconf: DeckConf) -> None: """Add an option tab for Straight Reward at Review section on Deckconf dialog.""" w = QWidget() form = dconf.form form.horizontalLayout_straight = QVBoxLayout() ##### GRID LAYOUT form.gridLayout_straight = get_grid_layout(form) form.horizontalLayout_straight.addWidget(form.gridLayout_straight) ##### ENABLE NOTIFICATIONS form.straightEnableNotificationsCheckBox = QCheckBox( "Enable Notifications", w) form.horizontalLayout_straight.addWidget( form.straightEnableNotificationsCheckBox) ##### STRETCH form.horizontalLayout_straight.addStretch() ##### FINISH UP w.setLayout(form.horizontalLayout_straight) positionBetweenReviewsAndLapses = 2 form.tabWidget.insertTab(positionBetweenReviewsAndLapses, w, "Rewards")
def __init__(self, parent, rootHtmlPath, size=None): super().__init__(parent) mw.setupDialogGC(self) self.setWindowFlags(Qt.Window) self.setWindowModality(Qt.WindowModal) # Populate content self.web = AnkiWebView() self.web._page._isMiniBrowser = True # Support window.close self.web._page.windowCloseRequested.connect(self.close) l = QVBoxLayout() l.setContentsMargins(0, 0, 0, 0) l.addWidget(self.web) self.setLayout(l) if type(size) == tuple: w, h = size self.resize(w, h) self.show() elif size is None: self.resize(800, 600) self.show() elif size == "maximized" or size == "maximize": self.resize(800, 600) self.showMaximized() elif size == "minimized" or size == "minimize": self.resize(800, 600) self.showMinimized() else: print("MiniBrowser - bad size (%s)" % size) self.resize(800, 600) self.show() # OK self.gotoLocalFile(rootHtmlPath)
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
class Previewer(QDialog): _last_state = None _card_changed = False _last_render: Union[int, float] = 0 _timer = None _show_both_sides = False def __init__(self, parent: QWidget, mw: AnkiQt, on_close: Callable[[], None]): super().__init__(None, Qt.Window) self._open = True self._parent = parent self._close_callback = on_close self.mw = mw icon = QIcon() icon.addPixmap(QPixmap(":/icons/anki.png"), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) def card(self) -> Optional[Card]: raise NotImplementedError def card_changed(self) -> bool: raise NotImplementedError def open(self): self._state = "question" self._last_state = None self._create_gui() self._setup_web_view() self.render_card() self.show() def _create_gui(self): self.setWindowTitle(tr(TR.ACTIONS_PREVIEW)) qconnect(self.finished, self._on_finished) self.silentlyClose = True self.vbox = QVBoxLayout() self.vbox.setContentsMargins(0, 0, 0, 0) self._web = AnkiWebView(title="previewer") self.vbox.addWidget(self._web) self.bbox = QDialogButtonBox() self._replay = self.bbox.addButton(tr(TR.ACTIONS_REPLAY_AUDIO), QDialogButtonBox.ActionRole) self._replay.setAutoDefault(False) self._replay.setShortcut(QKeySequence("R")) self._replay.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="R")) qconnect(self._replay.clicked, self._on_replay_audio) both_sides_button = QCheckBox(tr(TR.QT_MISC_BACK_SIDE_ONLY)) both_sides_button.setShortcut(QKeySequence("B")) both_sides_button.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="B")) self.bbox.addButton(both_sides_button, QDialogButtonBox.ActionRole) self._show_both_sides = self.mw.col.conf.get("previewBothSides", False) both_sides_button.setChecked(self._show_both_sides) qconnect(both_sides_button.toggled, self._on_show_both_sides) self.vbox.addWidget(self.bbox) self.setLayout(self.vbox) restoreGeom(self, "preview") def _on_finished(self, ok): saveGeom(self, "preview") self.mw.progress.timer(100, self._on_close, False) def _on_replay_audio(self): if self._state == "question": replay_audio(self.card(), True) elif self._state == "answer": replay_audio(self.card(), False) def close(self): self._on_close() super().close() def _on_close(self): self._open = False self._close_callback() def _setup_web_view(self): jsinc = [ "js/vendor/jquery.min.js", "js/vendor/browsersel.js", "js/mathjax.js", "js/vendor/mathjax/tex-chtml.js", "js/reviewer.js", ] self._web.stdHtml( self.mw.reviewer.revHtml(), css=["css/reviewer.css"], js=jsinc, context=self, ) self._web.set_bridge_command(self._on_bridge_cmd, self) def _on_bridge_cmd(self, cmd: str) -> Any: if cmd.startswith("play:"): play_clicked_audio(cmd, self.card()) def render_card(self): self.cancel_timer() # Keep track of whether render() has ever been called # with cardChanged=True since the last successful render self._card_changed |= self.card_changed() # avoid rendering in quick succession elap_ms = int((time.time() - self._last_render) * 1000) delay = 300 if elap_ms < delay: self._timer = self.mw.progress.timer(delay - elap_ms, self._render_scheduled, False) else: self._render_scheduled() def cancel_timer(self): if self._timer: self._timer.stop() self._timer = None def _render_scheduled(self) -> None: self.cancel_timer() self._last_render = time.time() if not self._open: return c = self.card() func = "_showQuestion" if not c: txt = tr(TR.QT_MISC_PLEASE_SELECT_1_CARD) bodyclass = "" self._last_state = None else: if self._show_both_sides: self._state = "answer" elif self._card_changed: self._state = "question" currentState = self._state_and_mod() if currentState == self._last_state: # nothing has changed, avoid refreshing return # need to force reload even if answer txt = c.q(reload=True) if self._state == "answer": func = "_showAnswer" txt = c.a() txt = re.sub(r"\[\[type:[^]]+\]\]", "", txt) bodyclass = theme_manager.body_classes_for_card_ord(c.ord) if c.autoplay(): AnkiWebView.setPlaybackRequiresGesture(False) if self._show_both_sides: # if we're showing both sides at once, remove any audio # from the answer that's appeared on the question already question_audio = c.question_av_tags() only_on_answer_audio = [ x for x in c.answer_av_tags() if x not in question_audio ] audio = question_audio + only_on_answer_audio elif self._state == "question": audio = c.question_av_tags() else: audio = c.answer_av_tags() av_player.play_tags(audio) else: AnkiWebView.setPlaybackRequiresGesture(True) av_player.clear_queue_and_maybe_interrupt() txt = self.mw.prepare_card_text_for_display(txt) txt = gui_hooks.card_will_show( txt, c, "preview" + self._state.capitalize()) self._last_state = self._state_and_mod() self._web.eval("{}({},'{}');".format(func, json.dumps(txt), bodyclass)) self._card_changed = False def _on_show_both_sides(self, toggle): self._show_both_sides = toggle self.mw.col.conf["previewBothSides"] = toggle self.mw.col.setMod() if self._state == "answer" and not toggle: self._state = "question" self.render_card() def _state_and_mod(self): c = self.card() n = c.note() n.load() return (self._state, c.id, n.mod) def state(self) -> str: return self._state
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\" 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:")) coll = QHBoxLayout() coll.addWidget(QLabel("In-app:")) coll.addWidget(ttcol) wtcol = QSpinBox() wtcol.setRange(1, 99) wtcol.setValue(config.wide) coll.addWidget(QLabel("Exported:")) coll.addWidget(wtcol) itcol = QCheckBox("Don't care") itcol.setChecked(addonconfig['defaults'].get("autothinwide", False)) def disableEnableColumnSettings(state): ttcol.setEnabled(state != Qt.Checked) wtcol.setEnabled(state != Qt.Checked) itcol.stateChanged.connect(disableEnableColumnSettings) disableEnableColumnSettings(itcol.checkState()) coll.addWidget(itcol) il.addLayout(coll) 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() config.autothinwide = itcol.isChecked() self.makegrid(config) mw.progress.finish() self.win.show()
def setup_evernote(self): global evernote_default_deck global evernote_default_tag global evernote_tags_to_import global keep_evernote_tags global update_existing_notes widget = QWidget() layout = QVBoxLayout() # Default Deck evernote_default_deck_label = QLabel("Default Deck:") evernote_default_deck = QLineEdit() evernote_default_deck.setText(mw.col.conf.get(SETTING_DEFAULT_DECK, "")) layout.insertWidget(int(layout.count()) + 1, evernote_default_deck_label) layout.insertWidget(int(layout.count()) + 2, evernote_default_deck) evernote_default_deck.connect(evernote_default_deck, SIGNAL("editingFinished()"), update_evernote_default_deck) # Default Tag evernote_default_tag_label = QLabel("Default Tag:") evernote_default_tag = QLineEdit() evernote_default_tag.setText(mw.col.conf.get(SETTING_DEFAULT_TAG, "")) layout.insertWidget(int(layout.count()) + 1, evernote_default_tag_label) layout.insertWidget(int(layout.count()) + 2, evernote_default_tag) evernote_default_tag.connect(evernote_default_tag, SIGNAL("editingFinished()"), update_evernote_default_tag) # Tags to Import evernote_tags_to_import_label = QLabel("Tags to Import:") evernote_tags_to_import = QLineEdit() evernote_tags_to_import.setText(mw.col.conf.get(SETTING_TAGS_TO_IMPORT, "")) layout.insertWidget(int(layout.count()) + 1, evernote_tags_to_import_label) layout.insertWidget(int(layout.count()) + 2, evernote_tags_to_import) evernote_tags_to_import.connect(evernote_tags_to_import, SIGNAL("editingFinished()"), update_evernote_tags_to_import) # Keep Evernote Tags keep_evernote_tags = QCheckBox("Keep Evernote Tags", self) keep_evernote_tags.setChecked(mw.col.conf.get(SETTING_KEEP_TAGS, False)) keep_evernote_tags.stateChanged.connect(update_evernote_keep_tags) layout.insertWidget(int(layout.count()) + 1, keep_evernote_tags) # Update Existing Notes updated_label = QLabel("Behavior if a note is already imported:") layout.insertWidget(int(layout.count()) + 1, updated_label) update_existing_notes = QComboBox() update_existing_notes.addItems(["Ignore (do nothing)", "Update (raise API usage, but useful if you tend to edit your cards in Evernote)", "Reset (same as Update, but cards are rescheduled)"]) update_existing_notes.setCurrentIndex(mw.col.conf.get(SETTING_UPDATE_EXISTING_NOTES, UpdateExistingNotes.UpdateNotesInPlace)) update_existing_notes.activated.connect(update_evernote_update_existing_notes) layout.insertWidget(int(layout.count()) + 1, update_existing_notes) deletebutton = QPushButton(_("Reset Account"), clicked=remove_token) layout.insertWidget(int(layout.count()) + 1, deletebutton) # Vertical Spacer vertical_spacer = QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) layout.addItem(vertical_spacer) # Parent Widget widget.setLayout(layout) # New Tab self.form.tabWidget.addTab(widget, "Evernote Importer")
def setup_evernote(self): global evernote_default_deck global evernote_default_tag global evernote_tags_to_import global keep_evernote_tags global update_existing_notes widget = QWidget() layout = QVBoxLayout() # Default Deck evernote_default_deck_label = QLabel("Default Deck:") evernote_default_deck = QLineEdit() evernote_default_deck.setText(mw.col.conf.get(SETTING_DEFAULT_DECK, "")) layout.insertWidget(int(layout.count()) + 1, evernote_default_deck_label) layout.insertWidget(int(layout.count()) + 2, evernote_default_deck) evernote_default_deck.connect(evernote_default_deck, SIGNAL("editingFinished()"), update_evernote_default_deck) # Default Tag evernote_default_tag_label = QLabel("Default Tag:") evernote_default_tag = QLineEdit() evernote_default_tag.setText(mw.col.conf.get(SETTING_DEFAULT_TAG, "")) layout.insertWidget(int(layout.count()) + 1, evernote_default_tag_label) layout.insertWidget(int(layout.count()) + 2, evernote_default_tag) evernote_default_tag.connect(evernote_default_tag, SIGNAL("editingFinished()"), update_evernote_default_tag) # Tags to Import evernote_tags_to_import_label = QLabel("Tags to Import:") evernote_tags_to_import = QLineEdit() evernote_tags_to_import.setText(mw.col.conf.get(SETTING_TAGS_TO_IMPORT, "")) layout.insertWidget(int(layout.count()) + 1, evernote_tags_to_import_label) layout.insertWidget(int(layout.count()) + 2, evernote_tags_to_import) evernote_tags_to_import.connect(evernote_tags_to_import, SIGNAL("editingFinished()"), update_evernote_tags_to_import) # Keep Evernote Tags keep_evernote_tags = QCheckBox("Keep Evernote Tags", self) keep_evernote_tags.setChecked(mw.col.conf.get(SETTING_KEEP_TAGS, False)) keep_evernote_tags.stateChanged.connect(update_evernote_keep_tags) layout.insertWidget(int(layout.count()) + 1, keep_evernote_tags) # Update Existing Notes update_existing_notes = QComboBox() update_existing_notes.addItems(["Ignore Existing Notes", "Update Existing Notes In-Place", "Delete and Re-Add Existing Notes"]) update_existing_notes.setCurrentIndex(mw.col.conf.get(SETTING_UPDATE_EXISTING_NOTES, UpdateExistingNotes.UpdateNotesInPlace)) update_existing_notes.activated.connect(update_evernote_update_existing_notes) layout.insertWidget(int(layout.count()) + 1, update_existing_notes) # Vertical Spacer vertical_spacer = QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) layout.addItem(vertical_spacer) # Parent Widget widget.setLayout(layout) # New Tab self.form.tabWidget.addTab(widget, "Evernote Importer")
def setup_evernote(self): global evernote_default_deck global evernote_default_tag global evernote_tags_to_import global keep_evernote_tags layout_tab = self.form.tab_1.layout() group_box = QGroupBox("Evernote Importer") layout = QVBoxLayout() # Default Deck evernote_default_deck_label = QLabel("Default Deck:") evernote_default_deck = QLineEdit() evernote_default_deck.setText(mw.col.conf.get('evernoteDefaultDeck', "")) layout.insertWidget(int(layout.count()) + 1, evernote_default_deck_label) layout.insertWidget(int(layout.count()) + 2, evernote_default_deck) evernote_default_deck.connect(evernote_default_deck, SIGNAL("editingFinished()"), update_evernote_default_deck) # Default Tag evernote_default_tag_label = QLabel("Default Tag:") evernote_default_tag = QLineEdit() evernote_default_tag.setText(mw.col.conf.get('evernoteDefaultTag', "")) layout.insertWidget(int(layout.count()) + 1, evernote_default_tag_label) layout.insertWidget(int(layout.count()) + 2, evernote_default_tag) evernote_default_tag.connect(evernote_default_tag, SIGNAL("editingFinished()"), update_evernote_default_tag) # Tags to import evernote_tags_to_import_label = QLabel("Tags to import:") evernote_tags_to_import = QLineEdit() evernote_tags_to_import.setText(mw.col.conf.get('evernoteTagsToImport', "")) layout.insertWidget(int(layout.count()) + 1, evernote_tags_to_import_label) layout.insertWidget(int(layout.count()) + 2, evernote_tags_to_import) evernote_tags_to_import.connect(evernote_tags_to_import, SIGNAL("editingFinished()"), update_evernote_tags_to_import) # keep evernote tags keep_evernote_tags = QCheckBox("Keep Evernote Tags", self) keep_evernote_tags.setChecked(mw.col.conf.get('evernoteKeepTags', False)) keep_evernote_tags.stateChanged.connect(update_evernote_keep_tags) layout.insertWidget(int(layout.count()) + 1, keep_evernote_tags) group_box.setLayout(layout) layout_tab.insertWidget(int(layout.count()) + 1, group_box)
def setup_evernote(self): global icoEvernoteWeb global imgEvernoteWeb global elements global evernote_query_last_updated global evernote_pagination_current_page_spinner def update_checkbox(setting): if setting is DECKS.EVERNOTE_NOTEBOOK_INTEGRATION and not elements[DECKS.BASE].text(): return if setting.get.startswith(QUERY.get): update_evernote_query_visibilities() setting.save(elements[setting].isChecked()) # mw.col.conf[setting] = if setting is QUERY.USE_TAGS: update_evernote_query_visibilities() if setting is QUERY.LAST_UPDATED.USE: evernote_query_last_updated_value_set_visibilities() def create_checkbox(setting, label=" ", default_value=False, is_fixed_size=False, fixed_width=None): if isinstance(label, bool): default_value = label label = " " checkbox = QCheckBox(label, self) sval = setting.fetch() if not isinstance(sval, bool): sval = default_value checkbox.setChecked(sval) # noinspection PyUnresolvedReferences checkbox.stateChanged.connect(lambda: update_checkbox(setting)) if is_fixed_size or fixed_width: checkbox.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) if fixed_width: checkbox.setFixedWidth(fixed_width) elements[setting] = checkbox return checkbox def create_checked_checkbox(*a, **kw): kw['default_value'] = True return create_checkbox(*a, **kw) def update_text(setting, text): text = text.strip() setting.save(text) if setting is DECKS.BASE: update_anki_deck_visibilities() if setting.get.startswith(QUERY.get): if text: use_key = getattr(QUERY, 'USE_' + setting.label.name) elements[use_key].setChecked(True) evernote_query_text_changed() if setting is QUERY.SEARCH_TERMS: update_evernote_query_visibilities() def create_textbox(setting, default_value=""): textbox = QLineEdit() textbox.setText(setting.fetch(default_value)) textbox.connect(textbox, SIGNAL("textEdited(QString)"), lambda text: update_text(setting, text)) elements[setting] = textbox return textbox def add_query_row(setting, is_checked=False, **kw): try: default_value = setting.val except: default_value = '' row_label = ' '.join(x.capitalize() for x in setting.replace('_', ' ').split()) hbox = QHBoxLayout() hbox.addWidget(create_checkbox(getattr(QUERY, 'USE_' + setting), default_value=is_checked, **kw)) hbox.addWidget(create_textbox(getattr(QUERY, setting), default_value)) form.addRow(row_label, hbox) def gen_qt_hr(): vbox = QVBoxLayout() hr = QFrame() hr.setAutoFillBackground(True) hr.setFrameShape(QFrame.HLine) hr.setStyleSheet("QFrame { background-color: #0060bf; color: #0060bf; }") hr.setFixedHeight(2) vbox.addWidget(hr) vbox.addSpacing(4) return vbox # Begin setup_evernote() widget = QWidget() layout = QVBoxLayout() elements = {} rm_log_path('Dicts\\') evernote_query_last_updated = DictCaseInsensitive() ########################## QUERY ########################## ##################### QUERY: TEXTBOXES #################### group = QGroupBox("EVERNOTE SEARCH OPTIONS:") group.setStyleSheet('QGroupBox{ font-size: 10px; font-weight: bold; color: rgb(105, 170, 53);}') form = QFormLayout() form.addRow(gen_qt_hr()) # Show Generated Evernote Query Button button_show_generated_evernote_query = QPushButton(icoEvernoteWeb, "Show Full Query", self) button_show_generated_evernote_query.setAutoDefault(False) button_show_generated_evernote_query.connect(button_show_generated_evernote_query, SIGNAL("clicked()"), handle_show_generated_evernote_query) # Add Form Row for Match Any Terms hbox = QHBoxLayout() hbox.addWidget(create_checked_checkbox(QUERY.ANY, " Match Any Terms", is_fixed_size=True)) hbox.addWidget(button_show_generated_evernote_query) form.addRow("<b>Search Parameters:</b>", hbox) # Add Form Rows for Evernote Query Textboxes for el in QUERY_TEXTBOXES: add_query_row(el, 'TAGS' in el) ################### QUERY: LAST UPDATED ################### # Evernote Query: Last Updated Type evernote_query_last_updated.type = QComboBox() evernote_query_last_updated.type.setStyleSheet(' QComboBox { color: rgb(45, 79, 201); font-weight: bold; } ') evernote_query_last_updated.type.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) evernote_query_last_updated.type.addItems([u"Δ Day", u"Δ Week", u"Δ Month", u"Δ Year", "Date", "+ Time"]) evernote_query_last_updated.type.setCurrentIndex(QUERY.LAST_UPDATED.TYPE.fetch(EvernoteQueryLocationType.RelativeDay)) evernote_query_last_updated.type.activated.connect(update_evernote_query_last_updated_type) # Evernote Query: Last Updated Type: Relative Date evernote_query_last_updated.value.relative.spinner = EvernoteQueryLocationValueQSpinBox() evernote_query_last_updated.value.relative.spinner.setVisible(False) evernote_query_last_updated.value.relative.spinner.setStyleSheet( " QSpinBox, EvernoteQueryLocationValueQSpinBox { font-weight: bold; color: rgb(173, 0, 0); } ") evernote_query_last_updated.value.relative.spinner.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) evernote_query_last_updated.value.relative.spinner.connect(evernote_query_last_updated.value.relative.spinner, SIGNAL("valueChanged(int)"), update_evernote_query_last_updated_value_relative_spinner) # Evernote Query: Last Updated Type: Absolute Date evernote_query_last_updated.value.absolute.date = QDateEdit() evernote_query_last_updated.value.absolute.date.setDisplayFormat('M/d/yy') evernote_query_last_updated.value.absolute.date.setCalendarPopup(True) evernote_query_last_updated.value.absolute.date.setVisible(False) evernote_query_last_updated.value.absolute.date.setStyleSheet( "QDateEdit { font-weight: bold; color: rgb(173, 0, 0); } ") evernote_query_last_updated.value.absolute.date.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) evernote_query_last_updated.value.absolute.date.connect(evernote_query_last_updated.value.absolute.date, SIGNAL("dateChanged(QDate)"), update_evernote_query_last_updated_value_absolute_date) # Evernote Query: Last Updated Type: Absolute DateTime evernote_query_last_updated.value.absolute.datetime = QDateTimeEdit() evernote_query_last_updated.value.absolute.datetime.setDisplayFormat('M/d/yy h:mm AP') evernote_query_last_updated.value.absolute.datetime.setCalendarPopup(True) evernote_query_last_updated.value.absolute.datetime.setVisible(False) evernote_query_last_updated.value.absolute.datetime.setStyleSheet( "QDateTimeEdit { font-weight: bold; color: rgb(173, 0, 0); } ") evernote_query_last_updated.value.absolute.datetime.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) evernote_query_last_updated.value.absolute.datetime.connect(evernote_query_last_updated.value.absolute.datetime, SIGNAL("dateTimeChanged(QDateTime)"), update_evernote_query_last_updated_value_absolute_datetime) # Evernote Query: Last Updated Type: Absolute Time evernote_query_last_updated.value.absolute.time = QTimeEdit() evernote_query_last_updated.value.absolute.time.setDisplayFormat('h:mm AP') evernote_query_last_updated.value.absolute.time.setVisible(False) evernote_query_last_updated.value.absolute.time.setStyleSheet( "QTimeEdit { font-weight: bold; color: rgb(143, 0, 30); } ") evernote_query_last_updated.value.absolute.time.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) evernote_query_last_updated.value.absolute.time.connect(evernote_query_last_updated.value.absolute.time, SIGNAL("timeChanged(QTime)"), update_evernote_query_last_updated_value_absolute_time) # Create HBox for Separated Date & Time hbox_datetime = QHBoxLayout() hbox_datetime.addWidget(evernote_query_last_updated.value.absolute.date) hbox_datetime.addWidget(evernote_query_last_updated.value.absolute.time) # Evernote Query: Last Updated Type evernote_query_last_updated.value.stacked_layout = QStackedLayout() evernote_query_last_updated.value.stacked_layout.addWidget(evernote_query_last_updated.value.relative.spinner) evernote_query_last_updated.value.stacked_layout.addItem(hbox_datetime) # Add Form Row for Evernote Query: Last Updated hbox = QHBoxLayout() label = QLabel("Last Updated: ") label.setMinimumWidth(SETTINGS.FORM.LABEL_MINIMUM_WIDTH.val) hbox.addWidget(create_checkbox(QUERY.LAST_UPDATED.USE, is_fixed_size=True)) hbox.addWidget(evernote_query_last_updated.type) hbox.addWidget(evernote_query_last_updated.value.relative.spinner) hbox.addWidget(evernote_query_last_updated.value.absolute.date) hbox.addWidget(evernote_query_last_updated.value.absolute.time) form.addRow(label, hbox) # Add Horizontal Row Separator form.addRow(gen_qt_hr()) ############################ PAGINATION ########################## # Evernote Pagination: Current Page evernote_pagination_current_page_spinner = QSpinBox() evernote_pagination_current_page_spinner.setStyleSheet("QSpinBox { font-weight: bold; color: rgb(173, 0, 0); } ") evernote_pagination_current_page_spinner.setPrefix("PAGE: ") evernote_pagination_current_page_spinner.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) evernote_pagination_current_page_spinner.setValue(EVERNOTE.PAGINATION_CURRENT_PAGE.fetch(1)) evernote_pagination_current_page_spinner.connect(evernote_pagination_current_page_spinner, SIGNAL("valueChanged(int)"), update_evernote_pagination_current_page_spinner) # Evernote Pagination: Automation hbox = QHBoxLayout() hbox.addWidget(create_checked_checkbox(EVERNOTE.AUTO_PAGING, " Automate", fixed_width=105)) hbox.addWidget(evernote_pagination_current_page_spinner) # Add Form Row for Evernote Pagination form.addRow("<b>Pagination:</b>", hbox) # Add Query Form to Group Box group.setLayout(form) # Add Query Group Box to Main Layout layout.addWidget(group) ########################## DECK ########################## # Setup Group Box and Form group = QGroupBox("ANKI NOTE OPTIONS:") group.setStyleSheet('QGroupBox{ font-size: 10px; font-weight: bold; color: rgb(105, 170, 53);}') form = QFormLayout() # Add Horizontal Row Separator form.addRow(gen_qt_hr()) # Add Form Row for Default Anki Deck hbox = QHBoxLayout() hbox.insertSpacing(0, 33) hbox.addWidget(create_textbox(DECKS.BASE, DECKS.BASE_DEFAULT_VALUE)) label_deck = QLabel("<b>Anki Deck:</b>") label_deck.setMinimumWidth(SETTINGS.FORM.LABEL_MINIMUM_WIDTH.val) form.addRow(label_deck, hbox) # Add Form Row for Evernote Notebook Integration label_deck = QLabel("Evernote Notebook:") label_deck.setMinimumWidth(SETTINGS.FORM.LABEL_MINIMUM_WIDTH.val) form.addRow("", create_checked_checkbox(DECKS.EVERNOTE_NOTEBOOK_INTEGRATION, " Append Evernote Notebook")) # Add Horizontal Row Separator form.addRow(gen_qt_hr()) ############################ TAGS ########################## # Add Form Row for Evernote Tag Options label = QLabel("<b>Evernote Tags:</b>") label.setMinimumWidth(SETTINGS.FORM.LABEL_MINIMUM_WIDTH.val) # Tags: Save To Anki Note form.addRow(label, create_checkbox(TAGS.KEEP_TAGS, " Save To Anki Note", TAGS.KEEP_TAGS_DEFAULT_VALUE)) hbox = QHBoxLayout() hbox.insertSpacing(0, 33) hbox.addWidget(create_textbox(TAGS.TO_DELETE)) # Tags: Tags To Delete form.addRow("Tags to Delete:", hbox) form.addRow(" ", create_checkbox(TAGS.DELETE_EVERNOTE_QUERY_TAGS, " Also Delete Search Tags")) # Add Horizontal Row Separator form.addRow(gen_qt_hr()) ############################ NOTE UPDATING ########################## # Note Update Method update_existing_notes = QComboBox() update_existing_notes.setStyleSheet( ' QComboBox { color: #3b679e; font-weight: bold; } QComboBoxItem { color: #A40F2D; font-weight: bold; } ') update_existing_notes.addItems(["Ignore Existing Notes", "Update In-Place", "Delete and Re-Add"]) sval = ANKI.UPDATE_EXISTING_NOTES.fetch() if not isinstance(sval, int): sval = ANKI.UPDATE_EXISTING_NOTES.val update_existing_notes.setCurrentIndex(sval) update_existing_notes.activated.connect(update_update_existing_notes) # Add Form Row for Note Update Method hbox = QHBoxLayout() hbox.insertSpacing(0, 33) hbox.addWidget(update_existing_notes) form.addRow("<b>Note Updating:</b>", hbox) # Add Note Update Method Form to Group Box group.setLayout(form) # Add Note Update Method Group Box to Main Layout layout.addWidget(group) ######################### UPDATE VISIBILITIES ####################### # Update Visibilities of Anki Deck Options update_anki_deck_visibilities() # Update Visibilities of Query Options evernote_query_text_changed() update_evernote_query_visibilities() ######################## ADD TO SETTINGS PANEL ###################### # Vertical Spacer vertical_spacer = QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) layout.addItem(vertical_spacer) # Parent Widget widget.setLayout(layout) # New Tab self.form.tabWidget.addTab(widget, "Anknotes")