def rebuild_template_map(self, key=None, attr=None): if not key: key = "t" attr = "tmpls" map_widget = getattr(self, key + "widg") layout = getattr(self, key + "layout") src = self.old_model[attr] dst = self.targetModel[attr] if map_widget: layout.removeWidget(map_widget) map_widget.deleteLater() setattr(self, key + "MapWidget", None) map_widget = QWidget() map_widget_layout = QGridLayout() combos = [] targets = [entity['name'] for entity in dst] + [_("Nothing")] indices = {} for i, entity in enumerate(src): map_widget_layout.addWidget(QLabel(_("Change %s to:") % entity['name']), i, 0) combo_box = QComboBox() combo_box.addItems(targets) idx = min(i, len(targets) - 1) combo_box.setCurrentIndex(idx) indices[combo_box] = idx combo_box.currentIndexChanged.connect( lambda entry_id: self.on_combo_changed(entry_id, combo_box, key)) combos.append(combo_box) map_widget_layout.addWidget(combo_box, i, 1) map_widget.setLayout(map_widget_layout) layout.addWidget(map_widget) setattr(self, key + "widg", map_widget) setattr(self, key + "layout", layout) setattr(self, key + "combos", combos) setattr(self, key + "indices", indices)
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 global update_existing_notes widget = QWidget() layout = QVBoxLayout() # Default Deck evernote_default_deck_label = QLabel("Default Deck for imported Cards:") 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 for imported Cards:") 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("Evernote 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, "Evernote2AnkiMac")
def keyPressEvent(self, evt): if evt.key() in (Qt.Key_Up, Qt.Key_Down): # show completer on arrow key up/down if not self.completer.popup().isVisible(): self.showCompleter() return if (evt.key() == Qt.Key_Tab and evt.modifiers() & Qt.ControlModifier): # select next completion if not self.completer.popup().isVisible(): self.showCompleter() index = self.completer.currentIndex() self.completer.popup().setCurrentIndex(index) cur_row = index.row() if not self.completer.setCurrentRow(cur_row + 1): self.completer.setCurrentRow(0) return if evt.key() in (Qt.Key_Enter, Qt.Key_Return): # apply first completion if no suggestion selected selected_row = self.completer.popup().currentIndex().row() if selected_row == -1: self.completer.setCurrentRow(0) index = self.completer.currentIndex() self.completer.popup().setCurrentIndex(index) self.hideCompleter() QWidget.keyPressEvent(self, evt) return QLineEdit.keyPressEvent(self, evt) if not evt.text(): # if it's a modifier, don't show return if evt.key() not in ( Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Space, Qt.Key_Tab, Qt.Key_Backspace, Qt.Key_Delete): self.showCompleter()
def showMapping(self, keepMapping=False, hook=None): if hook: hook() if not keepMapping: self.mapping = self.importer.mapping self.frm.mappingGroup.show() assert self.importer.fields() # set up the mapping grid if self.mapwidget: self.mapbox.removeWidget(self.mapwidget) self.mapwidget.deleteLater() self.mapwidget = QWidget() self.mapbox.addWidget(self.mapwidget) self.grid = QGridLayout(self.mapwidget) self.mapwidget.setLayout(self.grid) self.grid.setContentsMargins(3, 3, 3, 3) self.grid.setSpacing(6) fields = self.importer.fields() for num in range(len(self.mapping)): text = _("Field <b>%d</b> of file is:") % (num + 1) self.grid.addWidget(QLabel(text), num, 0) if self.mapping[num] == "_tags": text = _("mapped to <b>Tags</b>") elif self.mapping[num]: text = _("mapped to <b>%s</b>") % self.mapping[num] else: text = _("<ignored>") self.grid.addWidget(QLabel(text), num, 1) button = QPushButton(_("Change")) self.grid.addWidget(button, num, 2) button.clicked.connect( lambda _, s=self, n=num: s.changeMappingNum(n))
def show_words_window(self): """ Show the second window of the utility. This window shows the new words that were extracted from the text. """ self.words_window = QWidget(mw, flags=QtCore.Qt.Window) vbox = QVBoxLayout() vbox.addWidget(QLabel("Enter your vocab size target:")) self.vocab_recommended_radio = QRadioButton( "{} (Recommended)".format(RECOMMENDED_TARGET_VOCAB_SIZE)) self.vocab_custom_radio = QRadioButton("Custom: ") self.vocab_custom_box = LineEditWithFocusedSignal() radio_hbox = QHBoxLayout() radio_hbox.addStretch(1) radio_hbox.addWidget(self.vocab_recommended_radio) radio_hbox.addStretch(2) radio_hbox.addWidget(self.vocab_custom_radio) radio_hbox.addWidget(self.vocab_custom_box) radio_hbox.addStretch(1) vbox.addLayout(radio_hbox) vbox.addWidget(QLabel("These are the new words you should learn:")) self.words_table = self.init_words_table() vbox.addWidget(self.words_table) continue_hbox = QHBoxLayout() continue_hbox.addStretch(1) continue_button = QPushButton("Continue") continue_hbox.addWidget(continue_button) vbox.addLayout(continue_hbox) self.words_window.setLayout(vbox) self.update_words_table() # TODO: for some reason, this disables the blinking cursor in `vocab_custom_box` self.vocab_custom_box.focused.connect( lambda: self.vocab_custom_radio.click()) self.vocab_recommended_radio.clicked.connect( lambda: self.update_words_table()) self.vocab_custom_radio.clicked.connect( lambda: self.update_words_table()) self.vocab_custom_box.textChanged.connect( lambda: self.update_words_table()) continue_button.clicked.connect( lambda: self.words_window_continue_action()) self.words_window.show()
def setupTopArea(self): self.topArea = QWidget() self.topAreaForm = aqt.forms.clayout_top.Ui_Form() self.topAreaForm.setupUi(self.topArea) self.topAreaForm.templateOptions.setText(_("Options") + " "+downArrow()) self.topAreaForm.templateOptions.clicked.connect(self.onMore) self.topAreaForm.templatesBox.currentIndexChanged.connect(self.onCardSelected)
def eventFilter(self, watched, event): if event.type() == QEvent.Type.KeyPress and event.matches( QKeySequence.StandardKey.InsertParagraphSeparator): self.return_pressed() return True else: return QWidget.eventFilter(self, watched, event)
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_grid_layout(form) -> QWidget: w = QWidget() gridLayout = QGridLayout() gridLayout.setColumnStretch(1, 5) gridLayout.setContentsMargins(0, 0, 0, 5) ##### STRAIGHT LENGTH form.straightLengthLabel = make_label(w, "Begin at straight of length") gridLayout.addWidget(form.straightLengthLabel, 1, 0, 1, 1) form.straightLengthSpinBox = make_spin_box(w, 0, 100, "") gridLayout.addWidget(form.straightLengthSpinBox, 1, 1, 1, 2) ##### BASE EASE form.straightBaseEaseLabel = make_label(w, "Base ease reward") gridLayout.addWidget(form.straightBaseEaseLabel, 2, 0, 1, 1) form.straightBaseEaseSpinBox = make_spin_box(w) gridLayout.addWidget(form.straightBaseEaseSpinBox, 2, 1, 1, 2) ##### STEP EASE form.straightStepEaseLabel = make_label(w, "Step ease reward") gridLayout.addWidget(form.straightStepEaseLabel, 3, 0, 1, 1) form.straightStepEaseSpinBox = make_spin_box(w) gridLayout.addWidget(form.straightStepEaseSpinBox, 3, 1, 1, 2) ##### START EASE form.straightStartEaseLabel = make_label(w, "Start at ease") gridLayout.addWidget(form.straightStartEaseLabel, 4, 0, 1, 1) form.straightStartEaseSpinBox = make_spin_box(w, 130) gridLayout.addWidget(form.straightStartEaseSpinBox, 4, 1, 1, 2) ##### STOP EASE form.straightStopEaseLabel = make_label(w, "Stop at ease") gridLayout.addWidget(form.straightStopEaseLabel, 5, 0, 1, 1) form.straightStopEaseSpinBox = make_spin_box(w, 130) gridLayout.addWidget(form.straightStopEaseSpinBox, 5, 1, 1, 2) w.setLayout(gridLayout) return w
def _rebuildMap(self, key): """ key -- either "t" or "f", for template or fields. What to edit. """ map = getattr(self, key + "widg") lay = getattr(self, key + "layout") if map: lay.removeWidget(map) map.deleteLater() setattr(self, key + "MapWidget", None) map = QWidget() l = QGridLayout() combos = [] targets = [template['name'] for template in getattr(self, key + "dst")] indices = {} sources = getattr(self, key + "src") sourcesNames = [template["name"] for template in sources] if getUserOption("Associate to same name"): assoc = eltToPos(sourcesNames, targets) else: assoc = enumerate(sourcesNames) for indexSrc, (indexDst, templateName) in enumerate(assoc): l.addWidget(QLabel(_("Change %s to:") % templateName), indexSrc, 0) cb = QComboBox() cb.addItems(targets + [_("Nothing")]) idx = min(indexDst, len(targets)) cb.setCurrentIndex(idx) indices[cb] = idx cb.currentIndexChanged.connect( lambda i, cb=cb, key=key: self.onComboChanged(i, cb, key)) combos.append(cb) l.addWidget(cb, indexSrc, 1) map.setLayout(l) lay.addWidget(map) setattr(self, key + "widg", map) setattr(self, key + "layout", lay) setattr(self, key + "combos", combos) setattr(self, key + "indices", indices)
def setupMainArea(self): w = self.mainArea = QWidget() l = QHBoxLayout() l.setContentsMargins(0,0,0,0) l.setSpacing(3) left = QWidget() # template area tform = self.tform = aqt.forms.template.Ui_Form() tform.setupUi(left) tform.label1.setText(" →") tform.label2.setText(" →") tform.labelc1.setText(" ↗") tform.labelc2.setText(" ↘") if self.style().objectName() == "gtk+": # gtk+ requires margins in inner layout tform.tlayout1.setContentsMargins(0, 11, 0, 0) tform.tlayout2.setContentsMargins(0, 11, 0, 0) tform.tlayout3.setContentsMargins(0, 11, 0, 0) tform.groupBox_3.setTitle(_( "Styling (shared between cards)")) tform.front.textChanged.connect(self.saveCard) tform.css.textChanged.connect(self.saveCard) tform.back.textChanged.connect(self.saveCard) l.addWidget(left, 5) # preview area right = QWidget() pform = self.pform = aqt.forms.preview.Ui_Form() pform.setupUi(right) if self.style().objectName() == "gtk+": # gtk+ requires margins in inner layout pform.frontPrevBox.setContentsMargins(0, 11, 0, 0) pform.backPrevBox.setContentsMargins(0, 11, 0, 0) self.setupWebviews() l.addWidget(right, 5) w.setLayout(l)
def rebuild_template_map(self, key=None, attr=None): if not key: key = "t" attr = "tmpls" map_widget = getattr(self, key + "widg") layout = getattr(self, key + "layout") src = self.old_model[attr] dst = self.targetModel[attr] if map_widget: layout.removeWidget(map_widget) map_widget.deleteLater() setattr(self, key + "MapWidget", None) map_widget = QWidget() map_widget_layout = QGridLayout() combos = [] targets = [entity['name'] for entity in dst] + [_("Nothing")] indices = {} for i, entity in enumerate(src): map_widget_layout.addWidget( QLabel(_("Change %s to:") % entity['name']), i, 0) combo_box = QComboBox() combo_box.addItems(targets) idx = min(i, len(targets) - 1) combo_box.setCurrentIndex(idx) indices[combo_box] = idx combo_box.currentIndexChanged.connect( lambda entry_id: self.on_combo_changed(entry_id, combo_box, key )) combos.append(combo_box) map_widget_layout.addWidget(combo_box, i, 1) map_widget.setLayout(map_widget_layout) layout.addWidget(map_widget) setattr(self, key + "widg", map_widget) setattr(self, key + "layout", layout) setattr(self, key + "combos", combos) setattr(self, key + "indices", indices)
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")
class PrestudyDialog: @classmethod def instantiate_and_run(cls): cls().show_text_entry_window() 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 text_entry_continue_action(self): self.input_text = self.input_text_box.toPlainText() self.text_entry_window.close() self.show_words_window() @cached_property def input_words(self) -> Set[str]: """ Return the input after segmenting into words. """ return list( extract(self.input_text, min_difficulty="B", max_vocab=self.word_target)) def show_words_window(self): """ Show the second window of the utility. This window shows the new words that were extracted from the text. """ self.words_window = QWidget(mw, flags=QtCore.Qt.Window) vbox = QVBoxLayout() vbox.addWidget(QLabel("Enter your vocab size target:")) self.vocab_recommended_radio = QRadioButton( "{} (Recommended)".format(RECOMMENDED_TARGET_VOCAB_SIZE)) self.vocab_custom_radio = QRadioButton("Custom: ") self.vocab_custom_box = LineEditWithFocusedSignal() radio_hbox = QHBoxLayout() radio_hbox.addStretch(1) radio_hbox.addWidget(self.vocab_recommended_radio) radio_hbox.addStretch(2) radio_hbox.addWidget(self.vocab_custom_radio) radio_hbox.addWidget(self.vocab_custom_box) radio_hbox.addStretch(1) vbox.addLayout(radio_hbox) vbox.addWidget(QLabel("These are the new words you should learn:")) self.words_table = self.init_words_table() vbox.addWidget(self.words_table) continue_hbox = QHBoxLayout() continue_hbox.addStretch(1) continue_button = QPushButton("Continue") continue_hbox.addWidget(continue_button) vbox.addLayout(continue_hbox) self.words_window.setLayout(vbox) self.update_words_table() # TODO: for some reason, this disables the blinking cursor in `vocab_custom_box` self.vocab_custom_box.focused.connect( lambda: self.vocab_custom_radio.click()) self.vocab_recommended_radio.clicked.connect( lambda: self.update_words_table()) self.vocab_custom_radio.clicked.connect( lambda: self.update_words_table()) self.vocab_custom_box.textChanged.connect( lambda: self.update_words_table()) continue_button.clicked.connect( lambda: self.words_window_continue_action()) self.words_window.show() def update_words_table(self): words_to_study = self.words_to_study self.words_table.setRowCount(len(words_to_study)) for i, term in enumerate(self.words_to_study): self.words_table.setItem(i, 0, QTableWidgetItem(term.word)) @property def words_to_study(self) -> List[Term]: print(f"UNKNOWN: {self.unknown_words}") return sorted(self.unknown_words, key=lambda w: w.rank) @property def word_target(self): if self.vocab_recommended_radio.isChecked(): return RECOMMENDED_TARGET_VOCAB_SIZE if self.vocab_custom_radio.isChecked(): try: return int(self.vocab_custom_box.text()) except ValueError: return 0 return 0 @cached_property def unknown_words(self) -> List[str]: """ Get words in the text that aren't already studied. """ return [ word for word in self.input_words if word not in self.words_already_studied ] @cached_property def words_already_studied(self) -> Set[str]: def words_for_query(query): notes = [mw.col.getNote(id_) for id_ in mw.col.findNotes(query)] rv = set() for note in notes: if "Korean" in note: rv.add(note["Korean"]) return rv suspended = words_for_query("is:suspended") not_suspended = words_for_query("-is:suspended") not_new = words_for_query("-is:new") return not_new | (suspended - not_suspended) def init_words_table(self, parent=None): """ Generates a widget that displays a table of words and definitions. :param word_def_pairs: list of (word, def) tuples :return: a widget """ return QTableWidget(0, 1, parent) def words_window_continue_action(self): final_touches_window = FinalTouchesWindow(self.words_to_study) self.words_window.close() final_touches_window.show()
self.controls = pinyin.forms.generated.builddb.Ui_BuildDB() self.controls.setupUi(self) if __name__ == "__main__": import sys import time import pinyin.forms.builddbcontroller import pinyin.mocks class MockDBBuilder(object): def build(self): print "Building!" time.sleep(5) print "Building done" app = QApplication(sys.argv) parent = QWidget() parent.resize(250, 150) parent.setWindowTitle('simple') builddb = BuildDB(parent) _controller = pinyin.forms.builddbcontroller.BuildDBController( builddb, pinyin.mocks.NullNotifier(), MockDBBuilder(), True) builddb.show() sys.exit(app.exec_())
self.parent = parent self.fieldWidgets = {} self.controls = pinyin.forms.generated.builddb.Ui_BuildDB() self.controls.setupUi(self) if __name__ == "__main__": import sys import time import pinyin.forms.builddbcontroller import pinyin.mocks class MockDBBuilder(object): def build(self): print "Building!" time.sleep(5) print "Building done" app = QApplication(sys.argv) parent = QWidget() parent.resize(250, 150) parent.setWindowTitle('simple') builddb = BuildDB(parent) _controller = pinyin.forms.builddbcontroller.BuildDBController(builddb, pinyin.mocks.NullNotifier(), MockDBBuilder(), True) builddb.show() sys.exit(app.exec_())
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")
class ImportDialog(QDialog): def __init__(self, mw, importer): QDialog.__init__(self, mw, Qt.Window) self.mw = mw self.importer = importer self.frm = aqt.forms.importing.Ui_ImportDialog() self.frm.setupUi(self) self.frm.buttonBox.button(QDialogButtonBox.Help).clicked.connect( self.helpRequested) self.setupMappingFrame() self.setupOptions() self.modelChanged() self.frm.autoDetect.setVisible(self.importer.needDelimiter) addHook("currentModelChanged", self.modelChanged) self.frm.autoDetect.clicked.connect(self.onDelimiter) self.updateDelimiterButtonText() self.frm.allowHTML.setChecked(self.mw.pm.profile.get( 'allowHTML', True)) self.frm.importMode.setCurrentIndex( self.mw.pm.profile.get('importMode', 1)) # import button b = QPushButton(_("Import")) self.frm.buttonBox.addButton(b, QDialogButtonBox.AcceptRole) self.exec_() def setupOptions(self): self.model = self.mw.col.models.current() self.modelChooser = aqt.modelchooser.ModelChooser(self.mw, self.frm.modelArea, label=False) self.deck = aqt.deckchooser.DeckChooser(self.mw, self.frm.deckArea, label=False) def modelChanged(self): self.importer.model = self.mw.col.models.current() self.importer.initMapping() self.showMapping() if self.mw.col.conf.get("addToCur", True): did = self.mw.col.conf['curDeck'] if self.mw.col.decks.isDyn(did): did = 1 else: did = self.importer.model['did'] #self.deck.setText(self.mw.col.decks.name(did)) def onDelimiter(self): str = getOnlyText(_("""\ By default, Anki will detect the character between fields, such as a tab, comma, and so on. If Anki is detecting the character incorrectly, you can enter it here. Use \\t to represent tab."""), self, help="importing") or "\t" str = str.replace("\\t", "\t") if len(str) > 1: showWarning( _("Multi-character separators are not supported. " "Please enter one character only.")) return self.hideMapping() def updateDelim(): self.importer.delimiter = str self.importer.updateDelimiter() self.showMapping(hook=updateDelim) self.updateDelimiterButtonText() def updateDelimiterButtonText(self): if not self.importer.needDelimiter: return if self.importer.delimiter: d = self.importer.delimiter else: d = self.importer.dialect.delimiter if d == "\t": d = _("Tab") elif d == ",": d = _("Comma") elif d == " ": d = _("Space") elif d == ";": d = _("Semicolon") elif d == ":": d = _("Colon") else: d = repr(d) txt = _("Fields separated by: %s") % d self.frm.autoDetect.setText(txt) def accept(self): self.importer.mapping = self.mapping if not self.importer.mappingOk(): showWarning(_("The first field of the note type must be mapped.")) return self.importer.importMode = self.frm.importMode.currentIndex() self.mw.pm.profile['importMode'] = self.importer.importMode self.importer.allowHTML = self.frm.allowHTML.isChecked() self.mw.pm.profile['allowHTML'] = self.importer.allowHTML did = self.deck.selectedId() if did != self.importer.model['did']: self.importer.model['did'] = did self.mw.col.models.save(self.importer.model) self.mw.col.decks.select(did) self.mw.progress.start(immediate=True) self.mw.checkpoint(_("Import")) try: self.importer.run() except UnicodeDecodeError: showUnicodeWarning() return except Exception as e: msg = _("Import failed.\n") err = repr(str(e)) if "1-character string" in err: msg += err elif "invalidTempFolder" in err: msg += self.mw.errorHandler.tempFolderMsg() else: msg += str(traceback.format_exc(), "ascii", "replace") showText(msg) return finally: self.mw.progress.finish() txt = _("Importing complete.") + "\n" if self.importer.log: txt += "\n".join(self.importer.log) self.close() showText(txt) self.mw.reset() 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 hideMapping(self): self.frm.mappingGroup.hide() def showMapping(self, keepMapping=False, hook=None): if hook: hook() if not keepMapping: self.mapping = self.importer.mapping self.frm.mappingGroup.show() assert self.importer.fields() # set up the mapping grid if self.mapwidget: self.mapbox.removeWidget(self.mapwidget) self.mapwidget.deleteLater() self.mapwidget = QWidget() self.mapbox.addWidget(self.mapwidget) self.grid = QGridLayout(self.mapwidget) self.mapwidget.setLayout(self.grid) self.grid.setContentsMargins(3, 3, 3, 3) self.grid.setSpacing(6) fields = self.importer.fields() for num in range(len(self.mapping)): text = _("Field <b>%d</b> of file is:") % (num + 1) self.grid.addWidget(QLabel(text), num, 0) if self.mapping[num] == "_tags": text = _("mapped to <b>Tags</b>") elif self.mapping[num]: text = _("mapped to <b>%s</b>") % self.mapping[num] else: text = _("<ignored>") self.grid.addWidget(QLabel(text), num, 1) button = QPushButton(_("Change")) self.grid.addWidget(button, num, 2) button.clicked.connect( lambda _, s=self, n=num: s.changeMappingNum(n)) def changeMappingNum(self, n): f = ChangeMap(self.mw, self.importer.model, self.mapping[n]).getField() try: # make sure we don't have it twice index = self.mapping.index(f) self.mapping[index] = None except ValueError: pass self.mapping[n] = f if getattr(self.importer, "delimiter", False): self.savedDelimiter = self.importer.delimiter def updateDelim(): self.importer.delimiter = self.savedDelimiter self.showMapping(hook=updateDelim, keepMapping=True) else: self.showMapping(keepMapping=True) def reject(self): self.modelChooser.cleanup() self.deck.cleanup() remHook("currentModelChanged", self.modelChanged) QDialog.reject(self) def helpRequested(self): openHelp("importing")
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")