Esempio n. 1
0
    def setupMainWindow(self):
        # main window
        self.form = aqt.forms.main.Ui_MainWindow()
        self.form.setupUi(self)
        # toolbar
        tweb = self.toolbarWeb = aqt.webview.AnkiWebView()
        tweb.title = "top toolbar"
        tweb.setFocusPolicy(Qt.WheelFocus)
        self.toolbar = aqt.toolbar.Toolbar(self, tweb)
        self.toolbar.draw()
        # main area
        self.web = aqt.webview.AnkiWebView()
        self.web.title = "main webview"
        self.web.setFocusPolicy(Qt.WheelFocus)
        self.web.setMinimumWidth(400)
        # bottom area
        sweb = self.bottomWeb = aqt.webview.AnkiWebView()
        sweb.title = "bottom toolbar"
        sweb.setFocusPolicy(Qt.WheelFocus)
        # add in a layout
        self.mainLayout = QVBoxLayout()
        self.mainLayout.setContentsMargins(0,0,0,0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(tweb)
        self.mainLayout.addWidget(self.web)
        self.mainLayout.addWidget(sweb)
        self.form.centralwidget.setLayout(self.mainLayout)

        # force webengine processes to load before cwd is changed
        if isWin:
            for o in self.web, self.bottomWeb:
                o.requiresCol = False
                o._domReady = False
                o._page.setContent(bytes("", "ascii"))
Esempio n. 2
0
    def _create_gui(self):
        self.setWindowTitle(tr(TR.ACTIONS_PREVIEW))

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

        self._replay = self.bbox.addButton(tr(TR.ACTIONS_REPLAY_AUDIO),
                                           QDialogButtonBox.ActionRole)
        self._replay.setAutoDefault(False)
        self._replay.setShortcut(QKeySequence("R"))
        self._replay.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="R"))
        qconnect(self._replay.clicked, self._on_replay_audio)

        both_sides_button = QCheckBox(tr(TR.QT_MISC_BACK_SIDE_ONLY))
        both_sides_button.setShortcut(QKeySequence("B"))
        both_sides_button.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="B"))
        self.bbox.addButton(both_sides_button, QDialogButtonBox.ActionRole)
        self._show_both_sides = self.mw.col.conf.get("previewBothSides", False)
        both_sides_button.setChecked(self._show_both_sides)
        qconnect(both_sides_button.toggled, self._on_show_both_sides)

        self.vbox.addWidget(self.bbox)
        self.setLayout(self.vbox)
        restoreGeom(self, "preview")
Esempio n. 3
0
    def _create_gui(self):
        self.setWindowTitle(_("Preview"))

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

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

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

        self.vbox.addWidget(self.bbox)
        self.setLayout(self.vbox)
        restoreGeom(self, "preview")
Esempio n. 4
0
    def _create_gui(self) -> None:
        self.setWindowTitle(tr.actions_preview())

        self.close_shortcut = QShortcut(QKeySequence("Ctrl+Shift+P"), self)
        qconnect(self.close_shortcut.activated, self.close)

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

        self._replay = self.bbox.addButton(
            tr.actions_replay_audio(), QDialogButtonBox.ButtonRole.ActionRole)
        self._replay.setAutoDefault(False)
        self._replay.setShortcut(QKeySequence("R"))
        self._replay.setToolTip(tr.actions_shortcut_key(val="R"))
        qconnect(self._replay.clicked, self._on_replay_audio)

        both_sides_button = QCheckBox(tr.qt_misc_back_side_only())
        both_sides_button.setShortcut(QKeySequence("B"))
        both_sides_button.setToolTip(tr.actions_shortcut_key(val="B"))
        self.bbox.addButton(both_sides_button,
                            QDialogButtonBox.ButtonRole.ActionRole)
        self._show_both_sides = self.mw.col.get_config_bool(
            Config.Bool.PREVIEW_BOTH_SIDES)
        both_sides_button.setChecked(self._show_both_sides)
        qconnect(both_sides_button.toggled, self._on_show_both_sides)

        self.vbox.addWidget(self.bbox)
        self.setLayout(self.vbox)
        restoreGeom(self, "preview")
Esempio n. 5
0
 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
Esempio n. 6
0
 def _setupUI(self):
     """Basic UI setup"""
     mainLayout = QVBoxLayout()
     self.label = QLabel("Please press the key combination\n"
                         "you would like to assign")
     self.label.setAlignment(Qt.AlignCenter)
     mainLayout.addWidget(self.label)
     self.setLayout(mainLayout)
     self.setWindowTitle("Grab key combination")
Esempio n. 7
0
def downloadMedia(url, editor):
    # Local file : just read the file content
    if url.startswith("file://"):
        try:
            url = url[7:]
            # On windows, paths tend to be prefixed by file:///
            # rather than file://, so we remove redundant slash.
            if re.match(r'^/[A-Za-z]:\\', url):
                url = url[1:]
            return open(url, 'rb').read()
        except OSError:
            pass

    app = editor.mw.app

    # Show download dialog
    d = QDialog(editor.parentWindow)
    d.setWindowTitle("Downloading media (0.0%)")
    d.setWindowModality(Qt.WindowModal)
    vbox = QVBoxLayout()
    label = QLabel(url)
    label.setWordWrap(True)
    vbox.addWidget(label)
    d.setLayout(vbox)
    d.show()

    # Download chunk by chunk for progress bar
    try:
        response = urllib2.urlopen(url)
        totSize = int(response.info().getheader('Content-Length').strip())
        currentRead = 0
        chunk_size = 16384
        chunks = []

        while True:
            chunk = response.read(chunk_size)
            currentRead += len(chunk)

            if not chunk:
                break

            d.setWindowTitle("Downloading media (%.1f%%)" %
                             (currentRead * 100.0 / totSize))
            app.processEvents()
            chunks.append(chunk)

        return ''.join(chunks)

    except urllib2.URLError:
        return None

    finally:
        d.close()
        del d
Esempio n. 8
0
    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()
Esempio n. 9
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)
Esempio n. 10
0
    def onTargetDeck(self):
        from aqt.tagedit import TagEdit
        t = self.card.template()
        d = QDialog(self)
        d.setWindowTitle("Anki")
        d.setMinimumWidth(400)
        l = QVBoxLayout()
        lab = QLabel(_("""\
Enter deck to place new %s cards in, or leave blank:""") %
                           self.card.template()['name'])
        lab.setWordWrap(True)
        l.addWidget(lab)
        te = TagEdit(d, type=1)
        te.setCol(self.col)
        l.addWidget(te)
        if t['did']:
            te.setText(self.col.decks.get(t['did'])['name'])
            te.selectAll()
        bb = QDialogButtonBox(QDialogButtonBox.Close)
        bb.rejected.connect(d.close)
        l.addWidget(bb)
        d.setLayout(l)
        d.exec_()
        if not te.text().strip():
            t['did'] = None
        else:
            t['did'] = self.col.decks.id(te.text())
Esempio n. 11
0
 def __init__(self, parent, question, help=None, edit=None, default="", \
              title="Anki", minWidth=400):
     QDialog.__init__(self, parent)
     self.setWindowTitle(title)
     self.question = question
     self.help = help
     self.qlabel = QLabel(question)
     self.setMinimumWidth(minWidth)
     v = QVBoxLayout()
     v.addWidget(self.qlabel)
     if not edit:
         edit = QLineEdit()
     self.l = edit
     if default:
         self.l.setText(default)
         self.l.selectAll()
     v.addWidget(self.l)
     buts = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
     if help:
         buts |= QDialogButtonBox.Help
     b = QDialogButtonBox(buts)
     v.addWidget(b)
     self.setLayout(v)
     b.button(QDialogButtonBox.Ok).clicked.connect(self.accept)
     b.button(QDialogButtonBox.Cancel).clicked.connect(self.reject)
     if help:
         b.button(QDialogButtonBox.Help).clicked.connect(self.helpRequested)
    def initUI(self):
        vlay = QVBoxLayout()
        self.input_line = PanelInputLine()
        self.list_box = QListWidget()
        for i in range(self.max_items):
            self.list_box.insertItem(i, '')
        vlay.addWidget(self.input_line)
        vlay.addWidget(self.list_box)
        self.buttonbox = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok
            | QDialogButtonBox.StandardButton.Cancel)
        vlay.addWidget(self.buttonbox)
        # self.buttonbox.accepted.disconnect(self.accept)
        #   leads to: TypeError: disconnect() failed between 'accepted' and 'accept'
        self.buttonbox.accepted.connect(self.accept)
        self.buttonbox.rejected.connect(self.reject)
        self.update_listbox()
        self.setLayout(vlay)
        self.resize(800, 350)
        restoreGeom(self, "TT/TIFP")
        self.list_box.setAlternatingRowColors(True)

        # connections
        self.input_line.im_changed.connect(self.text_changed)
        self.input_line.textChanged.connect(self.text_changed)
        self.input_line.returnPressed.connect(self.return_pressed)
        self.input_line.down_pressed.connect(self.down_pressed)
        self.input_line.up_pressed.connect(self.up_pressed)
        self.list_box.itemDoubleClicked.connect(self.item_doubleclicked)
        self.list_box.installEventFilter(self)
        self.input_line.setFocus()
Esempio n. 13
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()
Esempio n. 14
0
File: sync.py Progetto: 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())
Esempio n. 15
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())
Esempio n. 16
0
    def __init__(self, parent, bodyhtml, jsSavecommand, wintitle, dialogname):
        super(ExtraWysiwygEditorForField, self).__init__(parent)

        self.jsSavecommand = jsSavecommand
        self.parent = parent
        self.setWindowTitle(wintitle)
        self.resize(810, 700)
        restoreGeom(self, "805891399_winsize")

        mainLayout = QVBoxLayout()
        mainLayout.setContentsMargins(0, 0, 0, 0)
        mainLayout.setSpacing(0)
        self.setLayout(mainLayout)
        self.web = MyWebView(self)  # maybe also self.parent?
        self.web.allowDrops = True  # default in webview/AnkiWebView is False
        self.web.title = dialogname
        self.web.contextMenuEvent = self.contextMenuEvent
        mainLayout.addWidget(self.web)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Save)
        mainLayout.addWidget(self.buttonBox)

        self.buttonBox.accepted.connect(self.onAccept)
        self.buttonBox.rejected.connect(self.onReject)
        QMetaObject.connectSlotsByName(self)
        acceptShortcut = QShortcut(QKeySequence("Ctrl+Return"), self)
        acceptShortcut.activated.connect(self.onAccept)

        zoomIn_Shortcut = QShortcut(QKeySequence("Ctrl++"), self)
        zoomIn_Shortcut.activated.connect(self.web.zoom_in)

        zoomOut_Shortcut = QShortcut(QKeySequence("Ctrl+-"), self)
        zoomOut_Shortcut.activated.connect(self.web.zoom_out)

        self.web.stdHtml(body=bodyhtml,
                         css=cssfiles,
                         js=addon_jsfiles + other_jsfiles,
                         head="",
                         context=self)
Esempio n. 17
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()
Esempio n. 18
0
    def updateWindow(self, html):

        if html is None:
            return False

        # build view
        webview = AnkiWebView()
        webview.stdHtml(html)

        # Clear old layout
        if self.__layout:
            QObjectCleanupHandler().add(self.__layout)

        # build layout
        self.__layout = QVBoxLayout()
        self.__layout.setContentsMargins(0, 0, 0, 0)
        self.__layout.addWidget(webview)

        # Update window
        self.setLayout(self.__layout)
        self.update()
Esempio n. 19
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()
Esempio n. 20
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()
Esempio n. 21
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)
Esempio n. 22
0
 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
Esempio n. 23
0
def chooseList(prompt, choices, startrow=0, parent=None):
    if not parent:
        parent = aqt.mw.app.activeWindow()
    d = QDialog(parent)
    d.setWindowModality(Qt.WindowModal)
    l = QVBoxLayout()
    d.setLayout(l)
    t = QLabel(prompt)
    l.addWidget(t)
    c = QListWidget()
    c.addItems(choices)
    c.setCurrentRow(startrow)
    l.addWidget(c)
    bb = QDialogButtonBox(QDialogButtonBox.Ok)
    bb.accepted.connect(d.accept)
    l.addWidget(bb)
    d.exec_()
    return c.currentRow()
Esempio n. 24
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
Esempio n. 25
0
    def _setupUI(self):
        vbox = QVBoxLayout()
        self.setLayout(vbox)

        self.lemmaLineEdit = LemmaLineEdit()
        vbox.addWidget(self.lemmaLineEdit)
        self.lemmaLineEdit.newLemmas.connect(self.setLemmas)

        self.ankiwordListWidget = AnkiwordListWidget(
            ankiInterface=self.ankiInterface)
        vbox.addWidget(self.ankiwordListWidget)

        self.show()
Esempio n. 26
0
    def onCheckMediaDB(self):
        self.progress.start(immediate=True)
        (nohave, unused, warnings) = self.col.media.check()
        self.progress.finish()
        # generate report
        report = ""
        if warnings:
            report += "\n".join(warnings) + "\n"
        if unused:
            if report:
                report += "\n\n\n"
            report += _(
                "In media folder but not used by any cards:")
            report += "\n" + "\n".join(unused)
        if nohave:
            if report:
                report += "\n\n\n"
            report += _(
                "Used on cards but missing from media folder:")
            report += "\n" + "\n".join(nohave)
        if not report:
            tooltip(_("No unused or missing files found."))
            return
        # show report and offer to delete
        diag = QDialog(self)
        diag.setWindowTitle("Anki")
        layout = QVBoxLayout(diag)
        diag.setLayout(layout)
        text = QTextEdit()
        text.setReadOnly(True)
        text.setPlainText(report)
        layout.addWidget(text)
        box = QDialogButtonBox(QDialogButtonBox.Close)
        layout.addWidget(box)
        if unused:
            b = QPushButton(_("Delete Unused Files"))
            b.setAutoDefault(False)
            box.addButton(b, QDialogButtonBox.ActionRole)
            b.clicked.connect(
                lambda c, u=unused, d=diag: self.deleteUnused(u, d))

        box.rejected.connect(diag.reject)
        diag.setMinimumHeight(400)
        diag.setMinimumWidth(500)
        restoreGeom(diag, "checkmediadb")
        diag.exec_()
        saveGeom(diag, "checkmediadb")
Esempio n. 27
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
Esempio n. 28
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")
Esempio n. 29
0
    def __init__(self, parent, rootHtmlPath, size=None):
        super().__init__(parent)
        mw.setupDialogGC(self)

        self.setWindowFlags(Qt.Window)
        self.setWindowModality(Qt.WindowModal)

        # Populate content
        self.web = AnkiWebView()
        self.web._page._isMiniBrowser = True
        # Support window.close
        self.web._page.windowCloseRequested.connect(self.close)
        l = QVBoxLayout()
        l.setContentsMargins(0, 0, 0, 0)
        l.addWidget(self.web)
        self.setLayout(l)

        if type(size) == tuple:
            w, h = size
            self.resize(w, h)
            self.show()

        elif size is None:
            self.resize(800, 600)
            self.show()

        elif size == "maximized" or size == "maximize":
            self.resize(800, 600)
            self.showMaximized()

        elif size == "minimized" or size == "minimize":
            self.resize(800, 600)
            self.showMinimized()

        else:
            print("MiniBrowser - bad size (%s)" % size)
            self.resize(800, 600)
            self.show()

        # OK
        self.gotoLocalFile(rootHtmlPath)
Esempio n. 30
0
def showText(txt, parent=None, type="text", run=True, geomKey=None, \
        minWidth=500, minHeight=400, title="Anki", copyBtn=False):
    if not parent:
        parent = aqt.mw.app.activeWindow() or aqt.mw
    diag = QDialog(parent)
    diag.setWindowTitle(title)
    layout = QVBoxLayout(diag)
    diag.setLayout(layout)
    text = QTextBrowser()
    text.setOpenExternalLinks(True)
    if type == "text":
        text.setPlainText(txt)
    else:
        text.setHtml(txt)
    layout.addWidget(text)
    box = QDialogButtonBox(QDialogButtonBox.Close)
    layout.addWidget(box)
    if copyBtn:
        def onCopy():
            QApplication.clipboard().setText(text.toPlainText())
        btn = QPushButton(_("Copy to Clipboard"))
        btn.clicked.connect(onCopy)
        box.addButton(btn, QDialogButtonBox.ActionRole)
    def onReject():
        if geomKey:
            saveGeom(diag, geomKey)
        QDialog.reject(diag)
    box.rejected.connect(onReject)
    def onFinish():
        if geomKey:
            saveGeom(diag, geomKey)
    box.accepted.connect(onFinish)
    diag.setMinimumHeight(minHeight)
    diag.setMinimumWidth(minWidth)
    if geomKey:
        restoreGeom(diag, geomKey)
    if run:
        diag.exec_()
    else:
        return diag, box
Esempio n. 31
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
        icon = QIcon()
        icon.addPixmap(QPixmap(":/icons/anki.png"), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)

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

    def card_changed(self) -> bool:
        raise NotImplementedError

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

    def _create_gui(self):
        self.setWindowTitle(tr(TR.ACTIONS_PREVIEW))

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

        self._replay = self.bbox.addButton(tr(TR.ACTIONS_REPLAY_AUDIO),
                                           QDialogButtonBox.ActionRole)
        self._replay.setAutoDefault(False)
        self._replay.setShortcut(QKeySequence("R"))
        self._replay.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="R"))
        qconnect(self._replay.clicked, self._on_replay_audio)

        both_sides_button = QCheckBox(tr(TR.QT_MISC_BACK_SIDE_ONLY))
        both_sides_button.setShortcut(QKeySequence("B"))
        both_sides_button.setToolTip(tr(TR.ACTIONS_SHORTCUT_KEY, val="B"))
        self.bbox.addButton(both_sides_button, QDialogButtonBox.ActionRole)
        self._show_both_sides = self.mw.col.conf.get("previewBothSides", False)
        both_sides_button.setChecked(self._show_both_sides)
        qconnect(both_sides_button.toggled, self._on_show_both_sides)

        self.vbox.addWidget(self.bbox)
        self.setLayout(self.vbox)
        restoreGeom(self, "preview")

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

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

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

    def _on_close(self):
        self._open = False
        self._close_callback()

    def _setup_web_view(self):
        jsinc = [
            "js/vendor/jquery.min.js",
            "js/vendor/browsersel.js",
            "js/mathjax.js",
            "js/vendor/mathjax/tex-chtml.js",
            "js/reviewer.js",
        ]
        self._web.stdHtml(
            self.mw.reviewer.revHtml(),
            css=["css/reviewer.css"],
            js=jsinc,
            context=self,
        )
        self._web.set_bridge_command(self._on_bridge_cmd, self)

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

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

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

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

        if not self._open:
            return
        c = self.card()
        func = "_showQuestion"
        if not c:
            txt = tr(TR.QT_MISC_PLEASE_SELECT_1_CARD)
            bodyclass = ""
            self._last_state = None
        else:
            if self._show_both_sides:
                self._state = "answer"
            elif self._card_changed:
                self._state = "question"

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

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

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

            bodyclass = theme_manager.body_classes_for_card_ord(c.ord)

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

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

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

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

    def state(self) -> str:
        return self._state
Esempio n. 32
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()
Esempio n. 33
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")
Esempio n. 34
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")
Esempio n. 35
0
def setup_evernote(self):
    global evernote_default_deck
    global evernote_default_tag
    global evernote_tags_to_import
    global keep_evernote_tags

    layout_tab = self.form.tab_1.layout()
    group_box = QGroupBox("Evernote Importer")
    layout = QVBoxLayout()

    # Default Deck
    evernote_default_deck_label = QLabel("Default Deck:")
    evernote_default_deck = QLineEdit()
    evernote_default_deck.setText(mw.col.conf.get('evernoteDefaultDeck', ""))
    layout.insertWidget(int(layout.count()) + 1, evernote_default_deck_label)
    layout.insertWidget(int(layout.count()) + 2, evernote_default_deck)
    evernote_default_deck.connect(evernote_default_deck, SIGNAL("editingFinished()"), update_evernote_default_deck)

    # Default Tag
    evernote_default_tag_label = QLabel("Default Tag:")
    evernote_default_tag = QLineEdit()
    evernote_default_tag.setText(mw.col.conf.get('evernoteDefaultTag', ""))
    layout.insertWidget(int(layout.count()) + 1, evernote_default_tag_label)
    layout.insertWidget(int(layout.count()) + 2, evernote_default_tag)
    evernote_default_tag.connect(evernote_default_tag, SIGNAL("editingFinished()"), update_evernote_default_tag)

    # Tags to import
    evernote_tags_to_import_label = QLabel("Tags to import:")
    evernote_tags_to_import = QLineEdit()
    evernote_tags_to_import.setText(mw.col.conf.get('evernoteTagsToImport', ""))
    layout.insertWidget(int(layout.count()) + 1, evernote_tags_to_import_label)
    layout.insertWidget(int(layout.count()) + 2, evernote_tags_to_import)
    evernote_tags_to_import.connect(evernote_tags_to_import,
                                    SIGNAL("editingFinished()"),
                                    update_evernote_tags_to_import)

    # keep evernote tags
    keep_evernote_tags = QCheckBox("Keep Evernote Tags", self)
    keep_evernote_tags.setChecked(mw.col.conf.get('evernoteKeepTags', False))
    keep_evernote_tags.stateChanged.connect(update_evernote_keep_tags)
    layout.insertWidget(int(layout.count()) + 1, keep_evernote_tags)
    group_box.setLayout(layout)
    layout_tab.insertWidget(int(layout.count()) + 1, group_box)
Esempio n. 36
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")