class MediaSyncDialog(QDialog): silentlyClose = True def __init__(self, mw: aqt.main.AnkiQt, syncer: MediaSyncer, close_when_done: bool = False) -> None: super().__init__(mw) self.mw = mw self._syncer = syncer self._close_when_done = close_when_done self.form = aqt.forms.synclog.Ui_Dialog() self.form.setupUi(self) self.setWindowTitle(tr(TR.SYNC_MEDIA_LOG_TITLE)) disable_help_button(self) self.abort_button = QPushButton(tr(TR.SYNC_ABORT_BUTTON)) qconnect(self.abort_button.clicked, self._on_abort) self.abort_button.setAutoDefault(False) self.form.buttonBox.addButton(self.abort_button, QDialogButtonBox.ActionRole) self.abort_button.setHidden(not self._syncer.is_syncing()) gui_hooks.media_sync_did_progress.append(self._on_log_entry) gui_hooks.media_sync_did_start_or_stop.append(self._on_start_stop) self.form.plainTextEdit.setPlainText("\n".join( self._entry_to_text(x) for x in syncer.entries())) self.form.plainTextEdit.moveCursor(QTextCursor.End) self.show() def reject(self) -> None: if self._close_when_done and self._syncer.is_syncing(): # closing while syncing on close starts an abort self._on_abort() return aqt.dialogs.markClosed("sync_log") QDialog.reject(self) def reopen(self, mw, syncer, close_when_done: bool = False) -> None: self._close_when_done = close_when_done self.show() def _on_abort(self, *args) -> None: self._syncer.abort() self.abort_button.setHidden(True) def _time_and_text(self, stamp: int, text: str) -> str: asctime = time.asctime(time.localtime(stamp)) return f"{asctime}: {text}" def _entry_to_text(self, entry: LogEntryWithTime): if isinstance(entry.entry, str): txt = entry.entry elif isinstance(entry.entry, MediaSyncProgress): txt = self._logentry_to_text(entry.entry) else: assert_exhaustive(entry.entry) return self._time_and_text(entry.time, txt) def _logentry_to_text(self, e: MediaSyncProgress) -> str: return f"{e.added}, {e.removed}, {e.checked}" def _on_log_entry(self, entry: LogEntryWithTime): self.form.plainTextEdit.appendPlainText(self._entry_to_text(entry)) if not self._syncer.is_syncing(): self.abort_button.setHidden(True) def _on_start_stop(self, running: bool) -> None: if not running and self._close_when_done: aqt.dialogs.markClosed("sync_log") self._close_when_done = False self.close()
def __init__(self, parent, tags, alltags): QDialog.__init__(self, parent, Qt.WindowType.Window) # super().__init__(parent) self.basic_mode = gc("dialog type: basic_but_quick") self.parent = parent self.alltags = alltags self.gridLayout = QGridLayout(self) self.gridLayout.setObjectName("gridLayout") self.label = QLabel("Edit tags:") self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.verticalLayout = QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.gridLayout.addLayout(self.verticalLayout, 1, 0, 1, 1) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Orientation.Horizontal) self.buttonBox.setStandardButtons( QDialogButtonBox.StandardButton.Cancel | QDialogButtonBox.StandardButton.Ok) self.shortcut = QShortcut(QKeySequence("Ctrl+Return"), self) self.shortcut.activated.connect(self.accept) self.helpButton = QPushButton( "add empty line", clicked=lambda: self.maybe_add_line(force=True)) self.buttonBox.addButton(self.helpButton, QDialogButtonBox.ButtonRole.HelpRole) self.filterbutton = QPushButton("edit tag for current line", clicked=self.tagselector) self.buttonBox.addButton(self.filterbutton, QDialogButtonBox.ButtonRole.ResetRole) self.searchButton = QPushButton( "search", clicked=lambda: self.do_browser_search(extra_search="")) self.buttonBox.addButton(self.searchButton, QDialogButtonBox.ButtonRole.ResetRole) self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 1) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.setWindowTitle("Anki - Edit Tags") originalheight = self.height() restoreGeom(self, "TagDialogExtended") self.resize(self.width(), originalheight) if not tags: tags = [ "", ] else: tags.append("") self.line_list = [] for t in tags: self.maybe_add_line(t) self.cut = gc("in tag lines dialog: open filterdialog for single tag") if self.cut: self.filterbutton.setToolTip('shortcut: {}'.format(self.cut)) self.selkey = QShortcut(QKeySequence(self.cut), self) self.selkey.activated.connect(self.tagselector) self.browser_scut = gc("in tag lines dialog: search browser for tag") if self.browser_scut: self.searchButton.setToolTip('shortcut: {}'.format( self.browser_scut)) self.browser_scut_key = QShortcut(QKeySequence(self.browser_scut), self) self.browser_scut_key.activated.connect( lambda: self.do_browser_search(extra_search="")) # don't also set Ctrl+t,a/gc("editor: show filterdialog to add single tag") for # self.tagselector: What if the user has already set them to the same etc. I'd have # to do a lot of checking self.addnl = gc("in tag lines dialog: insert additional line") if self.addnl: self.helpButton.setToolTip('shortcut: {}'.format(self.addnl)) self.addnlscut = QShortcut(QKeySequence(self.addnl), self) self.addnlscut.activated.connect( lambda: self.maybe_add_line(force=True))
class SingleCardPreviewerMod(SingleCardPreviewer): def _on_bridge_cmd(self, cmd): super()._on_bridge_cmd(cmd) def _create_gui(self): super()._create_gui() self.vbox.removeWidget(self.bbox) self.bottombar = QHBoxLayout() self.browser_button = QPushButton("show in browser") #self.browser_button.setShortcut(QKeySequence("b")) #self.browser_button.setToolTip("Shortcut key: %s" % "b") self.browser_button.clicked.connect(self._on_browser_button) self.bottombar.addWidget(self.browser_button) self.edit_button = self.bbox.addButton("edit", QDialogButtonBox.ButtonRole.HelpRole) #self.edit_button.setShortcut(QKeySequence("e")) #self.edit_button.setToolTip("Shortcut key: %s" % "e") self.edit_button.clicked.connect(self._on_edit_button) self.bottombar.addWidget(self.edit_button) self.showRate = QPushButton("G") # grade - "R" is already used for replay audio self.showRate.setFixedWidth(25) # self.showRate.setShortcut(QKeySequence("g")) # self.showRate.setToolTip("Shortcut key: %s" % "G") self.showRate.clicked.connect(self.onShowRatingBar) # self.bottombar.addWidget(self.showRate) self.bottombar.addWidget(self.bbox) self.vbox.addLayout(self.bottombar) def _setup_web_view(self): super()._setup_web_view() for child in self.bbox.children(): if isinstance(child, QCheckBox): self.both_sides_button = child self._show_both_sides = self.check_preview_both_config() self.both_sides_button.setChecked(self._show_both_sides) def check_preview_both_config(self): # if True both sides are shown showboth = False if gc("card_preview__default_is_answer"): showboth ^= True overrides = gc("card_preview__override_toggle_from_default_for_notetypes") if my_point_version() <= 49: name = self.card().model()['name'] else: name = self.card().note_type()['name'] if name in overrides: showboth ^= True return showboth def _on_browser_button(self): tooltip('browser clicked') browser = aqt.dialogs.open("Browser", self.mw) query = '"nid:' + str(self.card().nid) + '"' browser.form.searchEdit.lineEdit().setText(query) browser.onSearchActivated() def _on_edit_button(self): note = self.mw.col.getNote(self.card().nid) d = EditNoteWindowFromThisLinkAddon(self.mw, note) d.show() QDialog.reject(self) def onShowRatingBar(self): pass
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()
class TagDialogExtended__BasicOrTagEdit(QDialog): def __init__(self, parent, tags, alltags): QDialog.__init__(self, parent, Qt.WindowType.Window) # super().__init__(parent) self.basic_mode = gc("dialog type: basic_but_quick") self.parent = parent self.alltags = alltags self.gridLayout = QGridLayout(self) self.gridLayout.setObjectName("gridLayout") self.label = QLabel("Edit tags:") self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.verticalLayout = QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.gridLayout.addLayout(self.verticalLayout, 1, 0, 1, 1) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Orientation.Horizontal) self.buttonBox.setStandardButtons( QDialogButtonBox.StandardButton.Cancel | QDialogButtonBox.StandardButton.Ok) self.shortcut = QShortcut(QKeySequence("Ctrl+Return"), self) self.shortcut.activated.connect(self.accept) self.helpButton = QPushButton( "add empty line", clicked=lambda: self.maybe_add_line(force=True)) self.buttonBox.addButton(self.helpButton, QDialogButtonBox.ButtonRole.HelpRole) self.filterbutton = QPushButton("edit tag for current line", clicked=self.tagselector) self.buttonBox.addButton(self.filterbutton, QDialogButtonBox.ButtonRole.ResetRole) self.searchButton = QPushButton( "search", clicked=lambda: self.do_browser_search(extra_search="")) self.buttonBox.addButton(self.searchButton, QDialogButtonBox.ButtonRole.ResetRole) self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 1) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.setWindowTitle("Anki - Edit Tags") originalheight = self.height() restoreGeom(self, "TagDialogExtended") self.resize(self.width(), originalheight) if not tags: tags = [ "", ] else: tags.append("") self.line_list = [] for t in tags: self.maybe_add_line(t) self.cut = gc("in tag lines dialog: open filterdialog for single tag") if self.cut: self.filterbutton.setToolTip('shortcut: {}'.format(self.cut)) self.selkey = QShortcut(QKeySequence(self.cut), self) self.selkey.activated.connect(self.tagselector) self.browser_scut = gc("in tag lines dialog: search browser for tag") if self.browser_scut: self.searchButton.setToolTip('shortcut: {}'.format( self.browser_scut)) self.browser_scut_key = QShortcut(QKeySequence(self.browser_scut), self) self.browser_scut_key.activated.connect( lambda: self.do_browser_search(extra_search="")) # don't also set Ctrl+t,a/gc("editor: show filterdialog to add single tag") for # self.tagselector: What if the user has already set them to the same etc. I'd have # to do a lot of checking self.addnl = gc("in tag lines dialog: insert additional line") if self.addnl: self.helpButton.setToolTip('shortcut: {}'.format(self.addnl)) self.addnlscut = QShortcut(QKeySequence(self.addnl), self) self.addnlscut.activated.connect( lambda: self.maybe_add_line(force=True)) def current_tags_list(self): return [t.text() for t in self.line_list if t] def do_browser_search(self, extra_search=""): # Use the current line's text or the last line if the current one is an empty line note_tags = self.current_tags_list() searched_tag = shared_variables.focused_line.text() or ( note_tags[-1] if len(note_tags) > 0 else "") if searched_tag: browser = dialogs.open('Browser', mw) browser.setFilter('tag:"{}*" {}'.format(searched_tag, extra_search)) self.accept() else: tooltip("empty tag was selected for search") def tagselector(self): text = shared_variables.focused_line.text() d = FilterDialog(parent=self, values=self.alltags, allownew=True, prefill=text) if d.exec(): shared_variables.focused_line.setText(d.selkey) else: shared_variables.focused_line.setFocus() def change_focus_by_one(self, Down=True): for index, edit in enumerate(self.line_list): if edit == shared_variables.focused_line: if Down: if index == len( self.line_list) - 1: # if in last line go up self.line_list[0].setFocus() break else: newidx = index + 1 self.line_list[newidx].setFocus() break else: # go up if index == 0: # if in last line go up newidx = len(self.line_list) - 1 self.line_list[newidx].setFocus() break else: self.line_list[index - 1].setFocus() break def maybe_add_line(self, tag="", force=False): if self.line_list and not self.line_list[-1].text( ) and not force: # last lineedit is empty: self.line_list[-1].setFocus() self.line_list[-1].setText(tag) else: if self.basic_mode: te = MyBasicEdit(self) te.setText(tag) self.verticalLayout.addWidget(te) te.setFocus() self.line_list.append(te) else: te = MyTagEdit(self) te.setCol(mw.col) te.setText(tag) self.verticalLayout.addWidget(te) te.hideCompleter() te.setFocus() self.line_list.append(te) def accept(self): self.tagstring = "" for t in self.line_list: if not self.basic_mode: t.hideCompleter() text = t.text() if text: self.tagstring += text + " " saveGeom(self, "TagDialogExtended") QDialog.accept(self) def reject(self): saveGeom(self, "TagDialogExtended") QDialog.reject(self)
class AddCards(QDialog): def __init__(self, mw): QDialog.__init__(self, None, Qt.Window) mw.setupDialogGC(self) self.mw = mw self.form = aqt.forms.addcards.Ui_Dialog() self.form.setupUi(self) self.setWindowTitle(_("Add")) self.setMinimumHeight(300) self.setMinimumWidth(400) self.setupChoosers() self.setupEditor() self.setupButtons() self.onReset() self.history = [] restoreGeom(self, "add") addHook('reset', self.onReset) addHook('currentModelChanged', self.onModelChange) addCloseShortcut(self) self.show() def setupEditor(self): self.editor = aqt.editor.Editor(self.mw, self.form.fieldsArea, self, True) def setupChoosers(self): self.modelChooser = aqt.modelchooser.ModelChooser( self.mw, self.form.modelArea) self.deckChooser = aqt.deckchooser.DeckChooser(self.mw, self.form.deckArea) def helpRequested(self): openHelp("addingnotes") def setupButtons(self): bb = self.form.buttonBox ar = QDialogButtonBox.ActionRole # add self.addButton = bb.addButton(_("Add"), ar) self.addButton.clicked.connect(self.addCards) self.addButton.setShortcut(QKeySequence("Ctrl+Return")) self.addButton.setToolTip(shortcut(_("Add (shortcut: ctrl+enter)"))) # close self.closeButton = QPushButton(_("Close")) self.closeButton.setAutoDefault(False) bb.addButton(self.closeButton, QDialogButtonBox.RejectRole) # help self.helpButton = QPushButton(_("Help"), clicked=self.helpRequested) self.helpButton.setAutoDefault(False) bb.addButton(self.helpButton, QDialogButtonBox.HelpRole) # history b = bb.addButton(_("History") + " " + downArrow(), ar) if isMac: sc = "Ctrl+Shift+H" else: sc = "Ctrl+H" b.setShortcut(QKeySequence(sc)) b.setToolTip(_("Shortcut: %s") % shortcut(sc)) b.clicked.connect(self.onHistory) b.setEnabled(False) self.historyButton = b def setAndFocusNote(self, note): self.editor.setNote(note, focusTo=0) def onModelChange(self): oldNote = self.editor.note note = self.mw.col.newNote() if oldNote: oldFields = list(oldNote.keys()) newFields = list(note.keys()) for n, f in enumerate(note.model()['flds']): fieldName = f['name'] try: oldFieldName = oldNote.model()['flds'][n]['name'] except IndexError: oldFieldName = None # copy identical fields if fieldName in oldFields: note[fieldName] = oldNote[fieldName] # set non-identical fields by field index elif oldFieldName and oldFieldName not in newFields: try: note.fields[n] = oldNote.fields[n] except IndexError: pass self.removeTempNote(oldNote) self.editor.setNote(note) def onReset(self, model=None, keep=False): oldNote = self.editor.note note = self.mw.col.newNote() flds = note.model()['flds'] # copy fields from old note if oldNote: if not keep: self.removeTempNote(oldNote) for n in range(len(note.fields)): try: if not keep or flds[n]['sticky']: note.fields[n] = oldNote.fields[n] else: note.fields[n] = "" except IndexError: break self.setAndFocusNote(note) def removeTempNote(self, note): if not note or not note.id: return # we don't have to worry about cards; just the note self.mw.col._remNotes([note.id]) def addHistory(self, note): self.history.insert(0, note.id) self.history = self.history[:15] self.historyButton.setEnabled(True) def onHistory(self): m = QMenu(self) for nid in self.history: if self.mw.col.findNotes("nid:%s" % nid): fields = self.mw.col.getNote(nid).fields txt = htmlToTextLine(", ".join(fields)) if len(txt) > 30: txt = txt[:30] + "..." a = m.addAction(_("Edit \"%s\"") % txt) a.triggered.connect(lambda b, nid=nid: self.editHistory(nid)) else: a = m.addAction(_("(Note deleted)")) a.setEnabled(False) runHook("AddCards.onHistory", self, m) m.exec_(self.historyButton.mapToGlobal(QPoint(0, 0))) def editHistory(self, nid): browser = aqt.dialogs.open("Browser", self.mw) browser.form.searchEdit.lineEdit().setText("nid:%d" % nid) browser.onSearchActivated() def addNote(self, note): note.model()['did'] = self.deckChooser.selectedId() ret = note.dupeOrEmpty() if ret == 1: showWarning(_("The first field is empty."), help="AddItems#AddError") return if '{{cloze:' in note.model()['tmpls'][0]['qfmt']: if not self.mw.col.models._availClozeOrds( note.model(), note.joinedFields(), False): if not askUser( _("You have a cloze deletion note type " "but have not made any cloze deletions. Proceed?")): return cards = self.mw.col.addNote(note) if not cards: showWarning(_("""\ The input you have provided would make an empty \ question on all cards."""), help="AddItems") return self.addHistory(note) self.mw.requireReset() return note def addCards(self): self.editor.saveNow(self._addCards) def _addCards(self): self.editor.saveAddModeVars() note = self.editor.note note = self.addNote(note) if not note: return tooltip(_("Added"), period=500) # stop anything playing clearAudioQueue() self.onReset(keep=True) self.mw.col.autosave() def keyPressEvent(self, evt): "Show answer on RET or register answer." if (evt.key() in (Qt.Key_Enter, Qt.Key_Return) and self.editor.tags.hasFocus()): evt.accept() return return QDialog.keyPressEvent(self, evt) def reject(self): self.ifCanClose(self._reject) def _reject(self): remHook('reset', self.onReset) remHook('currentModelChanged', self.onModelChange) clearAudioQueue() self.removeTempNote(self.editor.note) self.editor.cleanup() self.modelChooser.cleanup() self.deckChooser.cleanup() self.mw.maybeReset() saveGeom(self, "add") aqt.dialogs.markClosed("AddCards") QDialog.reject(self) def ifCanClose(self, onOk): def afterSave(): ok = (self.editor.fieldsAreBlank() or askUser(_("Close and lose current input?"))) if ok: onOk() self.editor.saveNow(afterSave) def closeWithCallback(self, cb): def doClose(): self._reject() cb() self.ifCanClose(doClose)
def setupUI(self): mainLayout = QVBoxLayout() self.setLayout(mainLayout) # add widgets to set height and width widthLabel = QLabel('width') heightLabel = QLabel('height') self.widthEdit = QLineEdit(self) self.widthValidate = self.validate_label() self.heightValidate = self.validate_label() self.widthEdit.textEdited.connect( lambda i, v=self.widthValidate: self.onchange(i, v)) self.heightEdit = QLineEdit(self) self.heightEdit.textEdited.connect( lambda i, v=self.heightValidate: self.onchange(i, v)) self.attr2qt["width"] = self.widthEdit self.attr2qt["height"] = self.heightEdit wLayout = QHBoxLayout() wLayout.addWidget(widthLabel) wLayout.addWidget(self.widthEdit) hLayout = QHBoxLayout() hLayout.addWidget(heightLabel) hLayout.addWidget(self.heightEdit) sizeInputLayout = QHBoxLayout() sizeInputLayout.addLayout(wLayout) sizeInputLayout.addLayout(hLayout) labelLayout = QHBoxLayout() labelLayout.addWidget(self.widthValidate) labelLayout.addWidget(self.heightValidate) sizeLayout = QVBoxLayout() sizeLayout.addLayout(sizeInputLayout) sizeLayout.addLayout(labelLayout) # add final layout to main layout mainLayout.addLayout(sizeLayout) mainLayout.addWidget(self.hLine()) # add min- sizes and max- sizes if self.config["min-size"]: minWidthLabel = QLabel("min-width") minHeightLabel = QLabel("min-height") self.minWidthEdit = QLineEdit(self) self.minHeightEdit = QLineEdit(self) minLayout = QHBoxLayout() minLayout.addWidget(minWidthLabel) minLayout.addWidget(self.minWidthEdit) minLayout.addWidget(minHeightLabel) minLayout.addWidget(self.minHeightEdit) self.minWidthEdit.textEdited.connect( lambda i, v=self.widthValidate: self.onchange(i, v)) self.minHeightEdit.textEdited.connect( lambda i, v=self.heightValidate: self.onchange(i, v)) self.attr2qt["min-width"] = self.minWidthEdit self.attr2qt["min-height"] = self.minHeightEdit mainLayout.addLayout(minLayout) mainLayout.addWidget(self.hLine()) if self.config["max-size"]: maxWidthLabel = QLabel("max-width") maxHeightLabel = QLabel("max-height") self.maxWidthEdit = QLineEdit(self) self.maxHeightEdit = QLineEdit(self) maxLayout = QHBoxLayout() maxLayout.addWidget(maxWidthLabel) maxLayout.addWidget(self.maxWidthEdit) maxLayout.addWidget(maxHeightLabel) maxLayout.addWidget(self.maxHeightEdit) self.maxWidthEdit.textEdited.connect( lambda i, v=self.widthValidate: self.onchange(i, v)) self.maxHeightEdit.textEdited.connect( lambda i, v=self.heightValidate: self.onchange(i, v)) self.attr2qt["max-width"] = self.maxWidthEdit self.attr2qt["max-height"] = self.maxHeightEdit mainLayout.addLayout(maxLayout) mainLayout.addWidget(self.hLine()) # add widgets to show original width, height owidthLabel = QLabel('original width') oheightLabel = QLabel('original height') self.originalWidth = QLineEdit(self) self.originalHeight = QLineEdit(self) self.disableLineEdit(self.originalWidth) self.disableLineEdit(self.originalHeight) sizeLayout2 = QHBoxLayout() sizeLayout2.addWidget(owidthLabel) sizeLayout2.addWidget(self.originalWidth) sizeLayout2.addWidget(oheightLabel) sizeLayout2.addWidget(self.originalHeight) mainLayout.addLayout(sizeLayout2) # add Image Occlusion related buttons if self.is_occl: mainLayout.addWidget(self.hLine()) occlLabel = QLabel("Image Occlusion") occlLabel.setStyleSheet("QLabel {font-weight : bold;}") mainLayout.addWidget(occlLabel) occlAllNote = QCheckBox("Apply to all notes") self.occlAllNote = occlAllNote occlLayout = QHBoxLayout() occlLayout.addWidget(occlAllNote) self.attr2qt["Apply to all notes"] = self.occlAllNote if self.curr_fld in self.main.all_occl_flds: occlAllFld = QCheckBox("Apply to all fields") self.occlAllFld = occlAllFld occlLayout.addWidget(occlAllFld) self.attr2qt["Apply to all fields"] = self.occlAllFld mainLayout.addLayout(occlLayout) # add buttons okButton = QPushButton("OK") okButton.clicked.connect(self.clicked_ok) okButton.setDefault(True) okButton.setShortcut("Ctrl+Return") cancelButton = QPushButton("Cancel") cancelButton.clicked.connect(self.clicked_cancel) resetButton = QPushButton("Default") resetButton.clicked.connect(self.clicked_defaults) btnLayout = QHBoxLayout() btnLayout.addStretch(1) btnLayout.addWidget(okButton) btnLayout.addWidget(cancelButton) btnLayout.addWidget(resetButton) mainLayout.addLayout(btnLayout) self.setWindowTitle('Style Editor') self.show()
class DeckChooser(QHBoxLayout): def __init__(self, mw, widget, label=True, start=None): QHBoxLayout.__init__(self) self.widget = widget self.mw = mw self.deck = mw.col self.label = label self.setContentsMargins(0,0,0,0) self.setSpacing(8) self.setupDecks() self.widget.setLayout(self) addHook('currentModelChanged', self.onModelChange) def setupDecks(self): if self.label: self.deckLabel = QLabel(_("Deck")) self.addWidget(self.deckLabel) # decks box self.deck = QPushButton(clicked=self.onDeckChange) self.deck.setToolTip(shortcut(_("Target Deck (Ctrl+D)"))) s = QShortcut(QKeySequence(_("Ctrl+D")), self.widget, activated=self.onDeckChange) self.addWidget(self.deck) # starting label if self.mw.col.conf.get("addToCur", True): col = self.mw.col did = col.conf['curDeck'] if col.decks.isDyn(did): # if they're reviewing, try default to current card c = self.mw.reviewer.card if self.mw.state == "review" and c: if not c.odid: did = c.did else: did = c.odid else: did = 1 self.setDeckName(self.mw.col.decks.nameOrNone( did) or _("Default")) else: self.setDeckName(self.mw.col.decks.nameOrNone( self.mw.col.models.current()['did']) or _("Default")) # layout sizePolicy = QSizePolicy( QSizePolicy.Policy(7), QSizePolicy.Policy(0)) self.deck.setSizePolicy(sizePolicy) def show(self): self.widget.show() def hide(self): self.widget.hide() def cleanup(self): remHook('currentModelChanged', self.onModelChange) def onModelChange(self): if not self.mw.col.conf.get("addToCur", True): self.setDeckName(self.mw.col.decks.nameOrNone( self.mw.col.models.current()['did']) or _("Default")) def onDeckChange(self): from aqt.studydeck import StudyDeck current = self.deckName() ret = StudyDeck( self.mw, current=current, accept=_("Choose"), title=_("Choose Deck"), help="addingnotes", cancel=False, parent=self.widget, geomKey="selectDeck") if ret.name: self.setDeckName(ret.name) def setDeckName(self, name): self.deck.setText(name.replace("&", "&&")) self._deckName = name def deckName(self): return self._deckName def selectedId(self): # save deck name name = self.deckName() if not name.strip(): did = 1 else: did = self.mw.col.decks.id(name) return did
class Hyperlink(QDialog): 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() @staticmethod def enable_ok_button(button, url, text): if url and text: button.setEnabled(True) else: button.setEnabled(False) @staticmethod def combine_to_hyperlink(url, text): # Create a hyperlink string, where `url` is the hyperlink reference # and `text` the content of the tag. text = escape_html_chars(text) if gc("remove whitespace from beginning and end of urls"): url = url.strip() if gc("encode_illegal_characters_in_links"): url = some_percent_encoding(url) out = "<a href=\"{0}\">{1}</a>".format(url, text) return out def reject(self): saveGeom(self, "318752047__add_hyperlink") QDialog.reject(self) def insert_anchor(self, url, text): # Inserts a HTML anchor `<a>` into the text field. self.replacement = self.combine_to_hyperlink(url, text) self.url = url self.text = text saveGeom(self, "318752047__add_hyperlink") self.accept()
class Hyperlink(QDialog): def __init__(self, editor, parent_window, selected_visible_text, selected_is_url=False): QDialog.__init__(self, parent_window, Qt.Window) self.editor_instance = editor self.parent_window = parent_window self.visible_text = selected_visible_text self.selected_is_url = selected_is_url self.setWindowTitle("Anki: Create a hyperlink") self.resize(500, 200) restoreGeom(self, "318752047__add_hyperlink") self.pb_ok = QPushButton("&OK", self) self.pb_ok.setEnabled(False) self.pb_ok.clicked.connect(self.store_hyperlink_and_close) self.pb_cancel = QPushButton("&Cancel", self) self.pb_cancel.clicked.connect(self.reject) self.url_label = QLabel("Link to:") self.url_edit = QLineEdit() self.url_edit.setPlaceholderText("URL") self.url_edit.textChanged.connect(self.maybe_enable_ok_button) self.text_label = QLabel("Text to display:") self.text_edit = QLineEdit() self.text_edit.setPlaceholderText("Text") self.text_edit.textChanged.connect(self.maybe_enable_ok_button) 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(self.url_label) self.dialog_vbox.addWidget(self.url_edit) self.dialog_vbox.addWidget(self.text_label) self.dialog_vbox.addWidget(self.text_edit) self.dialog_vbox.addLayout(self.button_bar) self.setLayout(self.dialog_vbox) # if user already selected text, put it in self.text_edit if self.visible_text: if self.selected_is_url: self.url_edit.setText(self.visible_text) self.text_edit.setFocus() else: self.text_edit.setText(self.visible_text) self.url_edit.setFocus() def maybe_enable_ok_button(self): if self.url_edit.text() and self.text_edit.text(): self.pb_ok.setEnabled(True) else: self.pb_ok.setEnabled(False) def reject(self): saveGeom(self, "318752047__add_hyperlink") QDialog.reject(self) def store_hyperlink_and_close(self): self.url = self.url_edit.text() self.text = self.text_edit.text() self.replacement = combine_to_hyperlink(self.url, self.text) saveGeom(self, "318752047__add_hyperlink") self.accept()
def show(mw): dialog = ClosableQDialog(mw) mw.setupDialogGC(dialog) abt = aqt.forms.about.Ui_About() abt.setupUi(dialog) # Copy debug info ###################################################################### def onCopy(): addmgr = mw.addonManager addons = "\n".join(addmgr.annotatedName(d) for d in addmgr.allAddons()) info = "\n".join((supportText(), "Add-ons:\n\n{}".format(addons))) QApplication.clipboard().setText(info) tooltip(_("Copied to clipboard"), parent=dialog) btn = QPushButton(_("Copy Debug Info")) btn.clicked.connect(onCopy) abt.buttonBox.addButton(btn, QDialogButtonBox.ActionRole) abt.buttonBox.button(QDialogButtonBox.Ok).setFocus() # WebView contents ###################################################################### abouttext = "<center><img src='/_anki/imgs/anki-logo-thin.png'></center>" abouttext += '<p>' + _("Anki is a friendly, intelligent spaced learning \ system. It's free and open source.") abouttext += "<p>" + _( "Anki is licensed under the AGPL3 license. Please see " "the license file in the source distribution for more information.") abouttext += '<p>' + _("Version %s") % versionWithBuild() + '<br>' abouttext += ("Qt %s PyQt %s<br>") % (QT_VERSION_STR, PYQT_VERSION_STR) abouttext += (_("<a href='%s'>Visit website</a>") % aqt.appWebsite) + \ "</span>" # automatically sorted; add new lines at the end allusers = sorted(( "Aaron Harsh", "Alex Fraser", "Andreas Klauer", "Andrew Wright", "Aristotelis P.", "Bernhard Ibertsberger", "C. van Rooyen", "Charlene Barina", "Christian Krause", "Christian Rusche", "Dave Druelinger", "David Smith", "Dmitry Mikheev", "Dotan Cohen", "Emilio Wuerges", "Emmanuel Jarri", "Frank Harper", "Gregor Skumavc", "Guillem Palau Salvà", "H. Mijail", "Henrik Enggaard Hansen", "Houssam Salem", "Ian Lewis", "Immanuel Asmus", "Iroiro", "Jarvik7", "Jin Eun-Deok", "Jo Nakashima", "Johanna Lindh", "Joseph Lorimer", "Julien Baley", "Jussi Määttä", "Kieran Clancy", "LaC", "Laurent Steffan", "Luca Ban", "Luciano Esposito", "Marco Giancotti", "Marcus Rubeus", "Mari Egami", "Mark Wilbur", "Matthew Duggan", "Matthew Holtz", "Meelis Vasser", "Michael Jürges", "Michael Keppler", "Michael Montague", "Michael Penkov", "Michal Čadil", "Morteza Salehi", "Nathanael Law", "Nguyễn Hào Khôi", "Nick Cook", "Niklas Laxström", "Norbert Nagold", "Ole Guldberg", "Pcsl88", "Petr Michalec", "Piotr Kubowicz", "Richard Colley", "Roland Sieker", "Samson Melamed", "Silja Ijas", "Snezana Lukic", "Soren Bjornstad", "Stefaan De Pooter", "Susanna Björverud", "Sylvain Durand", "Tacutu", "Timm Preetz", "Timo Paulssen", "Ursus", "Victor Suba", "Volker Jansen", "Volodymyr Goncharenko", "Xtru", "Ádám Szegi", "赵金鹏", "黃文龍", "David Bailey", "Arman High", "Arthur Milchior", )) abouttext += '<p>' + _( "Written by Damien Elmes, with patches, translation,\ testing and design from:<p>%(cont)s") % { 'cont': ", ".join(allusers) } abouttext += '<p>' + _("If you have contributed and are not on this list, \ please get in touch.") abouttext += '<p>' + _("A big thanks to all the people who have provided \ suggestions, bug reports and donations.") abt.label.setMinimumWidth(800) abt.label.setMinimumHeight(600) dialog.show() abt.label.stdHtml(abouttext, js=" ") return dialog
class ModelChooser(QHBoxLayout): def __init__(self, mw, widget, label=True): QHBoxLayout.__init__(self) self.widget = widget self.mw = mw self.deck = mw.col self.label = label self.setContentsMargins(0, 0, 0, 0) self.setSpacing(8) self.setupModels() addHook('reset', self.onReset) self.widget.setLayout(self) def setupModels(self): if self.label: self.modelLabel = QLabel(_("Type")) self.addWidget(self.modelLabel) # models box self.models = QPushButton() #self.models.setStyleSheet("* { text-align: left; }") self.models.setToolTip(shortcut(_("Change Note Type (Ctrl+N)"))) s = QShortcut(QKeySequence(_("Ctrl+N")), self.widget, activated=self.onModelChange) self.models.setAutoDefault(False) self.addWidget(self.models) self.models.clicked.connect(self.onModelChange) # layout sizePolicy = QSizePolicy(QSizePolicy.Policy(7), QSizePolicy.Policy(0)) self.models.setSizePolicy(sizePolicy) self.updateModels() def cleanup(self): remHook('reset', self.onReset) def onReset(self): self.updateModels() def show(self): self.widget.show() def hide(self): self.widget.hide() def onEdit(self): import aqt.models aqt.models.Models(self.mw, self.widget) def onModelChange(self): from aqt.studydeck import StudyDeck current = self.deck.models.current()['name'] # edit button edit = QPushButton(_("Manage"), clicked=self.onEdit) def nameFunc(): return sorted(self.deck.models.allNames()) ret = StudyDeck(self.mw, names=nameFunc, accept=_("Choose"), title=_("Choose Note Type"), help="_notes", current=current, parent=self.widget, buttons=[edit], cancel=True, geomKey="selectModel") if not ret.name: return m = self.deck.models.byName(ret.name) self.deck.conf['curModel'] = m['id'] cdeck = self.deck.decks.current() cdeck['mid'] = m['id'] self.deck.decks.save(cdeck) runHook("currentModelChanged") self.mw.reset() def updateModels(self): self.models.setText(self.deck.models.current()['name'])
def setupButtons(self): l = self.buttons = QHBoxLayout() help = QPushButton(_("Help")) help.setAutoDefault(False) l.addWidget(help) help.clicked.connect(self.onHelp) l.addStretch() addField = QPushButton(_("Add Field")) addField.setAutoDefault(False) l.addWidget(addField) addField.clicked.connect(self.onAddField) if not self._isCloze(): flip = QPushButton(_("Flip")) flip.setAutoDefault(False) l.addWidget(flip) flip.clicked.connect(self.onFlip) l.addStretch() close = QPushButton(_("Close")) close.setAutoDefault(False) l.addWidget(close) close.clicked.connect(self.accept)
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")