Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
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")
Ejemplo n.º 3
0
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")
Ejemplo n.º 4
0
 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()
Ejemplo n.º 5
0
 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))
Ejemplo n.º 6
0
    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()
Ejemplo n.º 7
0
 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)
Ejemplo n.º 9
0
    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()
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
 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)
Ejemplo n.º 14
0
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")
Ejemplo n.º 15
0
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()
Ejemplo n.º 16
0
        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_())
Ejemplo n.º 17
0
        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_())
Ejemplo n.º 18
0
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")
Ejemplo n.º 19
0
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")
Ejemplo n.º 20
0
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")