Ejemplo n.º 1
0
    def _setupUi(self):
        flabel = QLabel("In this field:")
        self.fsel = QComboBox()
        fields = self._getFields()
        self.fsel.addItems(fields)
        self.cb = QCheckBox()
        self.cb.setText("transform to plain text")
        f_hbox = QHBoxLayout()
        f_hbox.addWidget(flabel)
        f_hbox.addWidget(self.fsel)
        f_hbox.addWidget(self.cb)
        f_hbox.setAlignment(Qt.AlignLeft)

        button_box = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
            orientation=Qt.Horizontal,
            parent=self,
        )

        bottom_hbox = QHBoxLayout()
        bottom_hbox.addWidget(button_box)

        vbox_main = QVBoxLayout()
        vbox_main.addLayout(f_hbox)
        vbox_main.addLayout(bottom_hbox)
        self.setLayout(vbox_main)
        self.setWindowTitle("Batch Clean Selected Notes")
        button_box.rejected.connect(self.reject)
        button_box.accepted.connect(self.accept)
        self.rejected.connect(self.reject)
        self.accepted.connect(self.accept)
        self.fsel.setFocus()
Ejemplo n.º 2
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.º 3
0
    def init_layout(self):
        self.setWindowTitle(" Prestudy")

        vbox = QVBoxLayout()

        vbox.addWidget(QLabel("Select deck to add notes to:"))
        self.combo_box = QComboBox(self)
        self.combo_box.addItems(self.deck_names)
        vbox.addWidget(self.combo_box)

        vbox.addWidget(
            QLabel(
                "(Optional) Enter tag(s) to add to notes, separated by spaces:"
            ))
        self.tags_box = QLineEdit()
        vbox.addWidget(self.tags_box)

        hbox = QHBoxLayout()
        self.finish_button = QPushButton("Add Notes")
        hbox.addStretch(1)
        hbox.addWidget(self.finish_button)
        vbox.addLayout(hbox)

        self.finish_button.clicked.connect(lambda: self.add_notes_action())

        self.setLayout(vbox)
Ejemplo n.º 4
0
    def _setup_ui(self):
        self.setWindowTitle("View Log")
        self.setMinimumWidth(600)
        self.setMinimumHeight(400)

        vbox = QVBoxLayout()
        vbox.addLayout(self._ui_top_row())
        vbox.addWidget(self._ui_log())
        vbox.addLayout(self._ui_bottom_row())

        self.setLayout(vbox)

        self.fillLog()
Ejemplo n.º 5
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()
    def hyperlink_dialog(self):
        dialog = QDialog(self.parent_window)
        dialog.setWindowTitle("Create a hyperlink")
        dialog.resize(DIALOG_SIZE_X, DIALOG_SIZE_Y)

        ok_button_anchor = QPushButton("&OK", dialog)
        ok_button_anchor.setEnabled(False)
        ok_button_anchor.clicked.connect(
            lambda: self.insert_anchor(url_edit.text(), urltext_edit.text()))
        ok_button_anchor.clicked.connect(dialog.hide)

        ok_button_anchor.setAutoDefault(True)

        cancel_button_anchor = QPushButton("&Cancel", dialog)
        cancel_button_anchor.clicked.connect(dialog.hide)
        cancel_button_anchor.setAutoDefault(True)

        url_label = QLabel("Link to:")
        url_edit = QLineEdit()
        url_edit.setPlaceholderText("URL")
        url_edit.textChanged.connect(lambda: self.enable_ok_button(
            ok_button_anchor, url_edit.text(), urltext_edit.text()))

        urltext_label = QLabel("Text to display:")
        urltext_edit = QLineEdit()
        urltext_edit.setPlaceholderText("Text")
        urltext_edit.textChanged.connect(lambda: self.enable_ok_button(
            ok_button_anchor, url_edit.text(), urltext_edit.text()))

        button_box = QHBoxLayout()
        button_box.addStretch(1)
        button_box.addWidget(cancel_button_anchor)
        button_box.addWidget(ok_button_anchor)

        dialog_vbox = QVBoxLayout()
        dialog_vbox.addWidget(url_label)
        dialog_vbox.addWidget(url_edit)
        dialog_vbox.addWidget(urltext_label)
        dialog_vbox.addWidget(urltext_edit)
        dialog_vbox.addLayout(button_box)
        dialog.setLayout(dialog_vbox)
        # if user already selected text, put it in urltext_edit
        if self.selected_text:
            if self.selected_is_url:
                url_edit.setText(self.selected_text)
                urltext_edit.setFocus()
            else:
                urltext_edit.setText(self.selected_text)
                url_edit.setFocus()
        dialog.exec()
Ejemplo n.º 7
0
Archivo: sync.py Proyecto: rye761/anki
def get_id_and_pass_from_user(mw: aqt.main.AnkiQt,
                              username: str = "",
                              password: str = "") -> tuple[str, str]:
    diag = QDialog(mw)
    diag.setWindowTitle("Anki")
    disable_help_button(diag)
    diag.setWindowModality(Qt.WindowModality.WindowModal)
    vbox = QVBoxLayout()
    info_label = QLabel(
        without_unicode_isolation(
            tr.sync_account_required(
                link="https://ankiweb.net/account/register")))
    info_label.setOpenExternalLinks(True)
    info_label.setWordWrap(True)
    vbox.addWidget(info_label)
    vbox.addSpacing(20)
    g = QGridLayout()
    l1 = QLabel(tr.sync_ankiweb_id_label())
    g.addWidget(l1, 0, 0)
    user = QLineEdit()
    user.setText(username)
    g.addWidget(user, 0, 1)
    l2 = QLabel(tr.sync_password_label())
    g.addWidget(l2, 1, 0)
    passwd = QLineEdit()
    passwd.setText(password)
    passwd.setEchoMode(QLineEdit.EchoMode.Password)
    g.addWidget(passwd, 1, 1)
    vbox.addLayout(g)
    bb = QDialogButtonBox(
        QDialogButtonBox.StandardButton.Ok
        | QDialogButtonBox.StandardButton.Cancel)  # type: ignore
    bb.button(QDialogButtonBox.StandardButton.Ok).setAutoDefault(True)
    qconnect(bb.accepted, diag.accept)
    qconnect(bb.rejected, diag.reject)
    vbox.addWidget(bb)
    diag.setLayout(vbox)
    diag.show()

    accepted = diag.exec()
    if not accepted:
        return ("", "")
    return (user.text().strip(), passwd.text())
Ejemplo n.º 8
0
def get_id_and_pass_from_user(mw: aqt.main.AnkiQt,
                              username="",
                              password="") -> Tuple[str, str]:
    diag = QDialog(mw)
    diag.setWindowTitle("Anki")
    diag.setWindowFlags(self.windowFlags()
                        & ~Qt.WindowContextHelpButtonHint)  # type: ignore
    diag.setWindowModality(Qt.WindowModal)
    vbox = QVBoxLayout()
    info_label = QLabel(
        without_unicode_isolation(
            tr(TR.SYNC_ACCOUNT_REQUIRED,
               link="https://ankiweb.net/account/register")))
    info_label.setOpenExternalLinks(True)
    info_label.setWordWrap(True)
    vbox.addWidget(info_label)
    vbox.addSpacing(20)
    g = QGridLayout()
    l1 = QLabel(tr(TR.SYNC_ANKIWEB_ID_LABEL))
    g.addWidget(l1, 0, 0)
    user = QLineEdit()
    user.setText(username)
    g.addWidget(user, 0, 1)
    l2 = QLabel(tr(TR.SYNC_PASSWORD_LABEL))
    g.addWidget(l2, 1, 0)
    passwd = QLineEdit()
    passwd.setText(password)
    passwd.setEchoMode(QLineEdit.Password)
    g.addWidget(passwd, 1, 1)
    vbox.addLayout(g)
    bb = QDialogButtonBox(QDialogButtonBox.Ok
                          | QDialogButtonBox.Cancel)  # type: ignore
    bb.button(QDialogButtonBox.Ok).setAutoDefault(True)
    qconnect(bb.accepted, diag.accept)
    qconnect(bb.rejected, diag.reject)
    vbox.addWidget(bb)
    diag.setLayout(vbox)
    diag.show()

    accepted = diag.exec_()
    if not accepted:
        return ("", "")
    return (user.text().strip(), passwd.text())
Ejemplo n.º 9
0
 def displaygrid(self, config, units):
     self.generate(config, units)
     self.win = QDialog(mw)
     self.wv = KanjiGridWebView()
     vl = QVBoxLayout()
     vl.setContentsMargins(0, 0, 0, 0)
     vl.addWidget(self.wv)
     self.wv.stdHtml(self.html)
     hl = QHBoxLayout()
     vl.addLayout(hl)
     sh = QPushButton("Save HTML", clicked=lambda: self.savehtml(config))
     hl.addWidget(sh)
     sp = QPushButton("Save Image", clicked=self.savepng)
     hl.addWidget(sp)
     bb = QPushButton("Close", clicked=self.win.reject)
     hl.addWidget(bb)
     self.win.setLayout(vl)
     self.win.resize(500, 400)
     self.timepoint("Window complete")
     return 0
Ejemplo n.º 10
0
 def displaygrid(self, config, units):
     self.generate(config, units)
     self.win = QDialog(mw)
     self.wv = KanjiGridWebView()
     vl = QVBoxLayout()
     vl.setContentsMargins(0, 0, 0, 0)
     vl.addWidget(self.wv)
     self.wv.stdHtml(self.html)
     hl = QHBoxLayout()
     vl.addLayout(hl)
     sh = QPushButton("Save HTML", clicked=lambda: self.savehtml(config))
     hl.addWidget(sh)
     sp = QPushButton("Save Image", clicked=self.savepng)
     hl.addWidget(sp)
     bb = QPushButton("Close", clicked=self.win.reject)
     hl.addWidget(bb)
     self.win.setLayout(vl)
     self.win.resize(500, 400)
     self.timepoint("Window complete")
     return 0
Ejemplo n.º 11
0
    def _getUserPass(self):
        d = QDialog(self.mw)
        d.setWindowTitle("Anki")
        d.setWindowModality(Qt.WindowModal)
        vbox = QVBoxLayout()
        l = QLabel(
            _("""\
<h1>Account Required</h1>
A free account is required to keep your collection synchronized. Please \
<a href="%s">sign up</a> for an account, then \
enter your details below.""") % "https://ankiweb.net/account/login")
        l.setOpenExternalLinks(True)
        l.setWordWrap(True)
        vbox.addWidget(l)
        vbox.addSpacing(20)
        g = QGridLayout()
        l1 = QLabel(_("AnkiWeb ID:"))
        g.addWidget(l1, 0, 0)
        user = QLineEdit()
        g.addWidget(user, 0, 1)
        l2 = QLabel(_("Password:"))
        g.addWidget(l2, 1, 0)
        passwd = QLineEdit()
        passwd.setEchoMode(QLineEdit.Password)
        g.addWidget(passwd, 1, 1)
        vbox.addLayout(g)
        bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bb.button(QDialogButtonBox.Ok).setAutoDefault(True)
        bb.accepted.connect(d.accept)
        bb.rejected.connect(d.reject)
        vbox.addWidget(bb)
        d.setLayout(vbox)
        d.show()
        accepted = d.exec_()
        u = user.text()
        p = passwd.text()
        if not accepted or not u or not p:
            return
        return (u, p)
Ejemplo n.º 12
0
 def __init__(self, mw, note, ord=0, parent=None, addMode=False):
     QDialog.__init__(self, parent or mw, Qt.Window)
     mw.setupDialogGC(self)
     self.mw = aqt.mw
     self.parent = parent or mw
     self.note = note
     self.ord = ord
     self.col = self.mw.col
     self.mm = self.mw.col.models
     self.model = note.model()
     self.mw.checkpoint(_("Card Types"))
     self.addMode = addMode
     if addMode:
         # save it to DB temporarily
         self.emptyFields = []
         for name, val in list(note.items()):
             if val.strip():
                 continue
             self.emptyFields.append(name)
             note[name] = "(%s)" % name
         note.flush()
     self.setupTopArea()
     self.setupMainArea()
     self.setupButtons()
     self.setupShortcuts()
     self.setWindowTitle(_("Card Types for %s") % self.model['name'])
     v1 = QVBoxLayout()
     v1.addWidget(self.topArea)
     v1.addWidget(self.mainArea)
     v1.addLayout(self.buttons)
     v1.setContentsMargins(12,12,12,12)
     self.setLayout(v1)
     self.redraw()
     restoreGeom(self, "CardLayout")
     self.setWindowModality(Qt.ApplicationModal)
     self.show()
     # take the focus away from the first input area when starting up,
     # as users tend to accidentally type into the template
     self.setFocus()
Ejemplo n.º 13
0
    def _setup_ui(self):
        self.setWindowTitle(self.title)
        self.setMinimumWidth(600)
        self.setMinimumHeight(400)

        vbox = QVBoxLayout()
        vbox.addLayout(self._ui_top_row())
        vbox.addLayout(self._ui_field_select_row())
        vbox.addWidget(self._ui_log())
        vbox.addLayout(self._ui_bottom_row())

        self.setLayout(vbox)
    def _setup_ui(self):
        self.setWindowTitle(self.title)
        self.setMinimumWidth(600)
        self.setMinimumHeight(400)

        vbox = QVBoxLayout()
        for row in self._ui_join_keys_row():
            vbox.addLayout(row)
        scroll_area = QScrollArea()
        inner = QFrame(scroll_area)
        vbox_scrollable = QVBoxLayout()
        inner.setLayout(vbox_scrollable)
        for row in self._ui_field_select_rows():
            vbox_scrollable.addLayout(row)
        scroll_area.setWidget(inner)

        splitter = QSplitter()
        splitter.setOrientation(Qt.Vertical)
        splitter.addWidget(scroll_area)
        splitter.addWidget(self._ui_log())
        vbox.addWidget(splitter)
        vbox.addLayout(self._ui_bottom_row())

        self.setLayout(vbox)
Ejemplo n.º 15
0
    def setupUI(self):
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)

        # add widgets to set height and width
        widthLabel = QLabel('width')
        heightLabel = QLabel('height')
        self.widthEdit = QLineEdit(self)
        self.widthValidate = self.validate_label()
        self.heightValidate = self.validate_label()
        self.widthEdit.textEdited.connect(
            lambda i, v=self.widthValidate: self.onchange(i, v))
        self.heightEdit = QLineEdit(self)
        self.heightEdit.textEdited.connect(
            lambda i, v=self.heightValidate: self.onchange(i, v))
        self.attr2qt["width"] = self.widthEdit
        self.attr2qt["height"] = self.heightEdit

        wLayout = QHBoxLayout()
        wLayout.addWidget(widthLabel)
        wLayout.addWidget(self.widthEdit)

        hLayout = QHBoxLayout()
        hLayout.addWidget(heightLabel)
        hLayout.addWidget(self.heightEdit)

        sizeInputLayout = QHBoxLayout()
        sizeInputLayout.addLayout(wLayout)
        sizeInputLayout.addLayout(hLayout)

        labelLayout = QHBoxLayout()
        labelLayout.addWidget(self.widthValidate)
        labelLayout.addWidget(self.heightValidate)

        sizeLayout = QVBoxLayout()
        sizeLayout.addLayout(sizeInputLayout)
        sizeLayout.addLayout(labelLayout)

        # add final layout to main layout
        mainLayout.addLayout(sizeLayout)
        mainLayout.addWidget(self.hLine())

        # add min- sizes and max- sizes
        if self.config["min-size"]:
            minWidthLabel = QLabel("min-width")
            minHeightLabel = QLabel("min-height")
            self.minWidthEdit = QLineEdit(self)
            self.minHeightEdit = QLineEdit(self)
            minLayout = QHBoxLayout()
            minLayout.addWidget(minWidthLabel)
            minLayout.addWidget(self.minWidthEdit)
            minLayout.addWidget(minHeightLabel)
            minLayout.addWidget(self.minHeightEdit)
            self.minWidthEdit.textEdited.connect(
                lambda i, v=self.widthValidate: self.onchange(i, v))
            self.minHeightEdit.textEdited.connect(
                lambda i, v=self.heightValidate: self.onchange(i, v))
            self.attr2qt["min-width"] = self.minWidthEdit
            self.attr2qt["min-height"] = self.minHeightEdit

            mainLayout.addLayout(minLayout)
            mainLayout.addWidget(self.hLine())

        if self.config["max-size"]:
            maxWidthLabel = QLabel("max-width")
            maxHeightLabel = QLabel("max-height")
            self.maxWidthEdit = QLineEdit(self)
            self.maxHeightEdit = QLineEdit(self)
            maxLayout = QHBoxLayout()
            maxLayout.addWidget(maxWidthLabel)
            maxLayout.addWidget(self.maxWidthEdit)
            maxLayout.addWidget(maxHeightLabel)
            maxLayout.addWidget(self.maxHeightEdit)
            self.maxWidthEdit.textEdited.connect(
                lambda i, v=self.widthValidate: self.onchange(i, v))
            self.maxHeightEdit.textEdited.connect(
                lambda i, v=self.heightValidate: self.onchange(i, v))
            self.attr2qt["max-width"] = self.maxWidthEdit
            self.attr2qt["max-height"] = self.maxHeightEdit

            mainLayout.addLayout(maxLayout)
            mainLayout.addWidget(self.hLine())

        # add widgets to show original width, height
        owidthLabel = QLabel('original width')
        oheightLabel = QLabel('original height')
        self.originalWidth = QLineEdit(self)
        self.originalHeight = QLineEdit(self)
        self.disableLineEdit(self.originalWidth)
        self.disableLineEdit(self.originalHeight)

        sizeLayout2 = QHBoxLayout()
        sizeLayout2.addWidget(owidthLabel)
        sizeLayout2.addWidget(self.originalWidth)
        sizeLayout2.addWidget(oheightLabel)
        sizeLayout2.addWidget(self.originalHeight)
        mainLayout.addLayout(sizeLayout2)

        # add Image Occlusion related buttons
        if self.is_occl:
            mainLayout.addWidget(self.hLine())
            occlLabel = QLabel("Image Occlusion")
            occlLabel.setStyleSheet("QLabel {font-weight : bold;}")
            mainLayout.addWidget(occlLabel)
            occlAllNote = QCheckBox("Apply to all notes")
            self.occlAllNote = occlAllNote
            occlLayout = QHBoxLayout()
            occlLayout.addWidget(occlAllNote)
            self.attr2qt["Apply to all notes"] = self.occlAllNote
            if self.curr_fld in self.main.all_occl_flds:
                occlAllFld = QCheckBox("Apply to all fields")
                self.occlAllFld = occlAllFld
                occlLayout.addWidget(occlAllFld)
                self.attr2qt["Apply to all fields"] = self.occlAllFld
            mainLayout.addLayout(occlLayout)

        # add buttons
        okButton = QPushButton("OK")
        okButton.clicked.connect(self.clicked_ok)
        okButton.setDefault(True)
        okButton.setShortcut("Ctrl+Return")
        cancelButton = QPushButton("Cancel")
        cancelButton.clicked.connect(self.clicked_cancel)
        resetButton = QPushButton("Default")
        resetButton.clicked.connect(self.clicked_defaults)

        btnLayout = QHBoxLayout()
        btnLayout.addStretch(1)
        btnLayout.addWidget(okButton)
        btnLayout.addWidget(cancelButton)
        btnLayout.addWidget(resetButton)
        mainLayout.addLayout(btnLayout)

        self.setWindowTitle('Style Editor')
        self.show()
Ejemplo n.º 16
0
    def setup(self):
        addonconfig = mw.addonManager.getConfig(__name__)
        config = types.SimpleNamespace(**addonconfig['defaults'])
        if addonconfig.get("_debug_time", False):
            self.timepoint = lambda c: print("%s: %0.3f" % (c, time.time()-self.time))
        else:
            self.timepoint = lambda _: None
        config.did = mw.col.conf['curDeck']

        swin = QDialog(mw)
        vl = QVBoxLayout()
        fl = QHBoxLayout()
        deckcb = QComboBox()
        deckcb.addItems(sorted(mw.col.decks.allNames()))
        deckcb.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        fl.addWidget(QLabel("Deck: "))
        deckcb.setCurrentText(mw.col.decks.get(config.did)['name'])
        def change_did(deckname):
            config.did = mw.col.decks.byName(deckname)['id']
        deckcb.currentTextChanged.connect(change_did)
        fl.addWidget(deckcb)
        vl.addLayout(fl)
        frm = QGroupBox("Settings")
        vl.addWidget(frm)
        il = QVBoxLayout()
        fl = QHBoxLayout()
        field = QLineEdit()
        field.setPlaceholderText("e.g. \"kanji\" or \"sentence-kanji\" (default: \"%s\")" % config.pattern)
        il.addWidget(QLabel("Pattern or Field names to search for (case insensitive):"))
        fl.addWidget(field)
        liter = QCheckBox("Match exactly")
        liter.setChecked(config.literal)
        fl.addWidget(liter)
        il.addLayout(fl)
        stint = QSpinBox()
        stint.setRange(1, 65536)
        stint.setValue(config.interval)
        il.addWidget(QLabel("Card interval considered strong:"))
        il.addWidget(stint)
        ttcol = QSpinBox()
        ttcol.setRange(1, 99)
        ttcol.setValue(config.thin)
        il.addWidget(QLabel("Number of Columns:"))
        coll = QHBoxLayout()
        coll.addWidget(QLabel("In-app:"))
        coll.addWidget(ttcol)
        wtcol = QSpinBox()
        wtcol.setRange(1, 99)
        wtcol.setValue(config.wide)
        coll.addWidget(QLabel("Exported:"))
        coll.addWidget(wtcol)
        itcol = QCheckBox("Don't care")
        itcol.setChecked(addonconfig['defaults'].get("autothinwide", False))
        def disableEnableColumnSettings(state):
            ttcol.setEnabled(state != Qt.Checked)
            wtcol.setEnabled(state != Qt.Checked)
        itcol.stateChanged.connect(disableEnableColumnSettings)
        disableEnableColumnSettings(itcol.checkState())
        coll.addWidget(itcol)
        il.addLayout(coll)
        groupby = QComboBox()
        groupby.addItems([
            *("None, sorted by " + x.pretty_value() for x in SortOrder),
            *(x.name for x in data.groups),
        ])
        groupby.setCurrentIndex(config.groupby)
        il.addWidget(QLabel("Group by:"))
        il.addWidget(groupby)
        shnew = QCheckBox("Show units not yet seen")
        shnew.setChecked(config.unseen)
        il.addWidget(shnew)
        toolt = QCheckBox("Show informational tooltips")
        toolt.setChecked(config.tooltips)
        il.addWidget(toolt)
        frm.setLayout(il)
        hl = QHBoxLayout()
        vl.addLayout(hl)
        gen = QPushButton("Generate", clicked=swin.accept)
        hl.addWidget(gen)
        cls = QPushButton("Close", clicked=swin.reject)
        hl.addWidget(cls)
        swin.setLayout(vl)
        swin.setTabOrder(gen, cls)
        swin.setTabOrder(cls, field)
        swin.setTabOrder(field, liter)
        swin.setTabOrder(liter, stint)
        swin.setTabOrder(stint, ttcol)
        swin.setTabOrder(ttcol, wtcol)
        swin.setTabOrder(wtcol, groupby)
        swin.setTabOrder(groupby, shnew)
        swin.setTabOrder(shnew, toolt)
        swin.resize(500, 400)
        if swin.exec_():
            mw.progress.start(immediate=True)
            if len(field.text().strip()) != 0:
                config.pattern = field.text().lower()
            config.pattern = config.pattern.split()
            config.literal = liter.isChecked()
            config.interval = stint.value()
            config.thin = ttcol.value()
            config.wide = wtcol.value()
            config.groupby = groupby.currentIndex()
            config.unseen = shnew.isChecked()
            config.tooltips = toolt.isChecked()
            config.autothinwide = itcol.isChecked()
            self.makegrid(config)
            mw.progress.finish()
            self.win.show()
Ejemplo n.º 17
0
class Previewer(QDialog):
    _last_state = None
    _card_changed = False
    _last_render: Union[int, float] = 0
    _timer = None
    _show_both_sides = False

    def __init__(self, parent: QWidget, mw: AnkiQt, on_close: Callable[[], None]):
        super().__init__(None, Qt.Window)
        self._open = True
        self._parent = parent
        self._close_callback = on_close
        self.mw = mw

    def card(self) -> Optional[Card]:
        raise NotImplementedError

    def open(self):
        self._state = "question"
        self._last_state = None
        self._create_gui()
        self._setup_web_view()
        self.render_card(True)
        self.show()

    def _create_gui(self):
        self.setWindowTitle(_("Preview"))

        qconnect(self.finished, self._on_finished)
        self.silentlyClose = True
        self.vbox = QVBoxLayout()
        self.vbox.setContentsMargins(0, 0, 0, 0)
        self._web = AnkiWebView(title="previewer")
        self.vbox.addWidget(self._web)
        self.bottombar = QHBoxLayout()
        self.bbox = QDialogButtonBox()

        self._replay = self.bbox.addButton(
            _("Replay Audio"), QDialogButtonBox.ActionRole
        )
        self._replay.setAutoDefault(False)
        self._replay.setShortcut(QKeySequence("R"))
        self._replay.setToolTip(_("Shortcut key: %s" % "R"))
        qconnect(self._replay.clicked, self._on_replay_audio)

        self.both_sides_button = QCheckBox(_("Show Both Sides"))
        self.both_sides_button.setShortcut(QKeySequence("B"))
        self.both_sides_button.setToolTip(_("Shortcut key: %s" % "B"))
        self.bbox.addButton(self.both_sides_button, QDialogButtonBox.ActionRole)
        self._show_both_sides = self.check_preview_both_config()
        self.both_sides_button.setChecked(self._show_both_sides)
        qconnect(self.both_sides_button.toggled, self._on_show_both_sides)

        self.bottombar.addWidget(self.bbox)
        self.vbox.addLayout(self.bottombar)
        self.setLayout(self.vbox)
        restoreGeom(self, "preview")
        
    def check_preview_both_config(self):
        return self.mw.col.conf.get("previewBothSides", False)

    def _on_finished(self, ok):
        saveGeom(self, "preview")
        self.mw.progress.timer(100, self._on_close, False)

    def _on_replay_audio(self):
        if self._state == "question":
            replay_audio(self.card(), True)
        elif self._state == "answer":
            replay_audio(self.card(), False)

    def close(self):
        self._on_close()
        super().close()
        self._close_callback()

    def _on_close(self):
        self._open = False

    def _setup_web_view(self):
        jsinc = [
            "jquery.js",
            "browsersel.js",
            "mathjax/conf.js",
            "mathjax/MathJax.js",
            "reviewer.js",
        ]
        self._web.stdHtml(
            self.mw.reviewer.revHtml(), css=["reviewer.css"], js=jsinc, context=self,
        )
        self._web.set_bridge_command(self._on_bridge_cmd, self)

    def _on_bridge_cmd(self, cmd: str) -> Any:
        if cmd.startswith("play:"):
            play_clicked_audio(cmd, self.card())

    def render_card(self, cardChanged=False):
        self.cancel_timer()
        # Keep track of whether render() has ever been called
        # with cardChanged=True since the last successful render
        self._card_changed |= cardChanged
        # avoid rendering in quick succession
        elap_ms = int((time.time() - self._last_render) * 1000)
        delay = 300
        if elap_ms < delay:
            self._timer = self.mw.progress.timer(
                delay - elap_ms, self._render_scheduled, False
            )
        else:
            self._render_scheduled()

    def cancel_timer(self):
        if self._timer:
            self._timer.stop()
            self._timer = None

    def _render_scheduled(self) -> None:
        self.cancel_timer()
        self._last_render = time.time()

        if not self._open:
            return
        c = self.card()
        func = "_showQuestion"
        if not c:
            txt = _("(please select 1 card)")
            bodyclass = ""
            self._last_state = None
        else:
            if self._show_both_sides:
                self._state = "answer"
            elif self._card_changed:
                self._state = "question"

            currentState = self._state_and_mod()
            if currentState == self._last_state:
                # nothing has changed, avoid refreshing
                return

            # need to force reload even if answer
            txt = c.q(reload=True)

            if self._state == "answer":
                func = "_showAnswer"
                txt = c.a()
            txt = re.sub(r"\[\[type:[^]]+\]\]", "", txt)

            bodyclass = theme_manager.body_classes_for_card_ord(c.ord)

            if c.autoplay():
                if self._show_both_sides:
                    # if we're showing both sides at once, remove any audio
                    # from the answer that's appeared on the question already
                    question_audio = c.question_av_tags()
                    only_on_answer_audio = [
                        x for x in c.answer_av_tags() if x not in question_audio
                    ]
                    audio = question_audio + only_on_answer_audio
                elif self._state == "question":
                    audio = c.question_av_tags()
                else:
                    audio = c.answer_av_tags()
                av_player.play_tags(audio)
            else:
                av_player.clear_queue_and_maybe_interrupt()

            txt = self.mw.prepare_card_text_for_display(txt)
            txt = gui_hooks.card_will_show(txt, c, "preview" + self._state.capitalize())
            self._last_state = self._state_and_mod()
        self._web.eval("{}({},'{}');".format(func, json.dumps(txt), bodyclass))
        self._card_changed = False

    def _on_show_both_sides(self, toggle):
        self._show_both_sides = toggle
        self.mw.col.conf["previewBothSides"] = toggle
        self.mw.col.setMod()
        if self._state == "answer" and not toggle:
            self._state = "question"
        self.render_card()

    def _state_and_mod(self):
        c = self.card()
        n = c.note()
        n.load()
        return (self._state, c.id, n.mod)

    def state(self) -> str:
        return self._state
Ejemplo n.º 18
0
class Hyperlink(QDialog):
    def __init__(self,
                 editor,
                 parent_window,
                 selected_visible_text,
                 selected_is_url=False):
        QDialog.__init__(self, parent_window, Qt.Window)
        self.editor_instance = editor
        self.parent_window = parent_window
        self.visible_text = selected_visible_text
        self.selected_is_url = selected_is_url
        self.setWindowTitle("Anki: Create a hyperlink")
        self.resize(500, 200)
        restoreGeom(self, "318752047__add_hyperlink")

        self.pb_ok = QPushButton("&OK", self)
        self.pb_ok.setEnabled(False)
        self.pb_ok.clicked.connect(self.store_hyperlink_and_close)

        self.pb_cancel = QPushButton("&Cancel", self)
        self.pb_cancel.clicked.connect(self.reject)

        self.url_label = QLabel("Link to:")
        self.url_edit = QLineEdit()
        self.url_edit.setPlaceholderText("URL")
        self.url_edit.textChanged.connect(self.maybe_enable_ok_button)

        self.text_label = QLabel("Text to display:")
        self.text_edit = QLineEdit()
        self.text_edit.setPlaceholderText("Text")
        self.text_edit.textChanged.connect(self.maybe_enable_ok_button)

        self.button_bar = QHBoxLayout()
        self.button_bar.addStretch(1)
        self.button_bar.addWidget(self.pb_cancel)
        self.button_bar.addWidget(self.pb_ok)

        self.dialog_vbox = QVBoxLayout()
        self.dialog_vbox.addWidget(self.url_label)
        self.dialog_vbox.addWidget(self.url_edit)
        self.dialog_vbox.addWidget(self.text_label)
        self.dialog_vbox.addWidget(self.text_edit)
        self.dialog_vbox.addLayout(self.button_bar)
        self.setLayout(self.dialog_vbox)

        # if user already selected text, put it in self.text_edit
        if self.visible_text:
            if self.selected_is_url:
                self.url_edit.setText(self.visible_text)
                self.text_edit.setFocus()
            else:
                self.text_edit.setText(self.visible_text)
                self.url_edit.setFocus()

    def maybe_enable_ok_button(self):
        if self.url_edit.text() and self.text_edit.text():
            self.pb_ok.setEnabled(True)
        else:
            self.pb_ok.setEnabled(False)

    def reject(self):
        saveGeom(self, "318752047__add_hyperlink")
        QDialog.reject(self)

    def store_hyperlink_and_close(self):
        self.url = self.url_edit.text()
        self.text = self.text_edit.text()
        self.replacement = combine_to_hyperlink(self.url, self.text)
        saveGeom(self, "318752047__add_hyperlink")
        self.accept()
Ejemplo n.º 19
0
class Hyperlink(QDialog):
    def __init__(self,
                 editor,
                 parent_window,
                 selected_text,
                 selected_is_url=False):
        QDialog.__init__(self, parent_window, Qt.Window)
        self.editor_instance = editor
        self.parent_window = parent_window
        self.selected_text = selected_text
        self.selected_is_url = selected_is_url
        self.setWindowTitle("Anki: Create a hyperlink")
        self.resize(DIALOG_SIZE_X, DIALOG_SIZE_Y)
        restoreGeom(self, "318752047__add_hyperlink")

        self.pb_ok = QPushButton("&OK", self)
        self.pb_ok.setEnabled(False)
        self.pb_ok.clicked.connect(
            lambda: self.insert_anchor(url_edit.text(), urltext_edit.text()))

        self.pb_cancel = QPushButton("&Cancel", self)
        self.pb_cancel.clicked.connect(self.reject)

        url_label = QLabel("Link to:")
        url_edit = QLineEdit()
        url_edit.setPlaceholderText("URL")
        url_edit.textChanged.connect(lambda: self.enable_ok_button(
            self.pb_ok, url_edit.text(), urltext_edit.text()))

        urltext_label = QLabel("Text to display:")
        urltext_edit = QLineEdit()
        urltext_edit.setPlaceholderText("Text")
        urltext_edit.textChanged.connect(lambda: self.enable_ok_button(
            self.pb_ok, url_edit.text(), urltext_edit.text()))

        self.button_bar = QHBoxLayout()
        self.button_bar.addStretch(1)
        self.button_bar.addWidget(self.pb_cancel)
        self.button_bar.addWidget(self.pb_ok)

        self.dialog_vbox = QVBoxLayout()
        self.dialog_vbox.addWidget(url_label)
        self.dialog_vbox.addWidget(url_edit)
        self.dialog_vbox.addWidget(urltext_label)
        self.dialog_vbox.addWidget(urltext_edit)
        self.dialog_vbox.addLayout(self.button_bar)
        self.setLayout(self.dialog_vbox)
        # if user already selected text, put it in urltext_edit
        if self.selected_text:
            if self.selected_is_url:
                url_edit.setText(self.selected_text)
                urltext_edit.setFocus()
            else:
                urltext_edit.setText(self.selected_text)
                url_edit.setFocus()

    @staticmethod
    def enable_ok_button(button, url, text):
        if url and text:
            button.setEnabled(True)
        else:
            button.setEnabled(False)

    @staticmethod
    def combine_to_hyperlink(url, text):
        # Create a hyperlink string, where `url` is the hyperlink reference
        # and `text` the content of the tag.
        text = escape_html_chars(text)
        if gc("remove whitespace from beginning and end of urls"):
            url = url.strip()
        if gc("encode_illegal_characters_in_links"):
            url = some_percent_encoding(url)
        out = "<a href=\"{0}\">{1}</a>".format(url, text)
        return out

    def reject(self):
        saveGeom(self, "318752047__add_hyperlink")
        QDialog.reject(self)

    def insert_anchor(self, url, text):
        # Inserts a HTML anchor `<a>` into the text field.
        self.replacement = self.combine_to_hyperlink(url, text)
        self.url = url
        self.text = text
        saveGeom(self, "318752047__add_hyperlink")
        self.accept()
Ejemplo n.º 20
0
    def setup(self):
        addonconfig = mw.addonManager.getConfig(__name__)
        config = types.SimpleNamespace(**addonconfig['defaults'])
        if addonconfig.get("_debug_time", False):
            self.timepoint = lambda c: print("%s: %0.3f" %
                                             (c, time.time() - self.time))
        else:
            self.timepoint = lambda _: None
        config.did = mw.col.conf['curDeck']

        swin = QDialog(mw)
        vl = QVBoxLayout()
        fl = QHBoxLayout()
        deckcb = QComboBox()
        deckcb.addItems(sorted(mw.col.decks.allNames()))
        deckcb.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        fl.addWidget(QLabel("Deck: "))
        deckcb.setCurrentText(mw.col.decks.get(config.did)['name'])

        def change_did(deckname):
            config.did = mw.col.decks.byName(deckname)['id']

        deckcb.currentTextChanged.connect(change_did)
        fl.addWidget(deckcb)
        vl.addLayout(fl)
        frm = QGroupBox("Settings")
        vl.addWidget(frm)
        il = QVBoxLayout()
        fl = QHBoxLayout()
        field = QLineEdit()
        field.setPlaceholderText(
            "e.g. \"kanji\", \"hanzi\" or \"sentence-kanji\" (default: \"%s\")"
            % config.pattern)
        il.addWidget(
            QLabel("Pattern or Field names to search for (case insensitive):"))
        fl.addWidget(field)
        liter = QCheckBox("Match exactly")
        liter.setChecked(config.literal)
        fl.addWidget(liter)
        il.addLayout(fl)
        stint = QSpinBox()
        stint.setRange(1, 65536)
        stint.setValue(config.interval)
        il.addWidget(QLabel("Card interval considered strong:"))
        il.addWidget(stint)
        ttcol = QSpinBox()
        ttcol.setRange(1, 99)
        ttcol.setValue(config.thin)
        il.addWidget(QLabel("Number of Columns in the in-app table:"))
        il.addWidget(ttcol)
        wtcol = QSpinBox()
        wtcol.setRange(1, 99)
        wtcol.setValue(config.wide)
        il.addWidget(QLabel("Number of Columns in the exported table:"))
        il.addWidget(wtcol)
        groupby = QComboBox()
        groupby.addItems([
            *("None, sorted by " + x.pretty_value() for x in SortOrder),
            *(x.name for x in data.groups),
        ])
        groupby.setCurrentIndex(config.groupby)
        il.addWidget(QLabel("Group by:"))
        il.addWidget(groupby)
        shnew = QCheckBox("Show units not yet seen")
        shnew.setChecked(config.unseen)
        il.addWidget(shnew)
        toolt = QCheckBox("Show informational tooltips")
        toolt.setChecked(config.tooltips)
        il.addWidget(toolt)
        frm.setLayout(il)
        hl = QHBoxLayout()
        vl.addLayout(hl)
        gen = QPushButton("Generate", clicked=swin.accept)
        hl.addWidget(gen)
        cls = QPushButton("Close", clicked=swin.reject)
        hl.addWidget(cls)
        swin.setLayout(vl)
        swin.setTabOrder(gen, cls)
        swin.setTabOrder(cls, field)
        swin.setTabOrder(field, liter)
        swin.setTabOrder(liter, stint)
        swin.setTabOrder(stint, ttcol)
        swin.setTabOrder(ttcol, wtcol)
        swin.setTabOrder(wtcol, groupby)
        swin.setTabOrder(groupby, shnew)
        swin.setTabOrder(shnew, toolt)
        swin.resize(500, 400)
        if swin.exec_():
            mw.progress.start(immediate=True)
            if len(field.text().strip()) != 0:
                config.pattern = field.text().lower()
            config.pattern = config.pattern.split()
            config.literal = liter.isChecked()
            config.interval = stint.value()
            config.thin = ttcol.value()
            config.wide = wtcol.value()
            config.groupby = groupby.currentIndex()
            config.unseen = shnew.isChecked()
            config.tooltips = toolt.isChecked()
            self.makegrid(config)
            mw.progress.finish()
            self.win.show()