Exemple #1
0
class BlockingBusy(QDialog):
    def __init__(self, msg, parent=None, window_title=_('Working')):
        QDialog.__init__(self, parent)

        self._layout = QVBoxLayout()
        self.setLayout(self._layout)
        self.msg = QLabel(msg)
        # self.msg.setWordWrap(True)
        self.font = QFont()
        self.font.setPointSize(self.font.pointSize() + 8)
        self.msg.setFont(self.font)
        self.pi = ProgressIndicator(self)
        self.pi.setDisplaySize(QSize(100, 100))
        self._layout.addWidget(self.pi, 0, Qt.AlignmentFlag.AlignHCenter)
        self._layout.addSpacing(15)
        self._layout.addWidget(self.msg, 0, Qt.AlignmentFlag.AlignHCenter)
        self.start()
        self.setWindowTitle(window_title)
        self.resize(self.sizeHint())

    def start(self):
        self.pi.startAnimation()

    def stop(self):
        self.pi.stopAnimation()

    def accept(self):
        self.stop()
        return QDialog.accept(self)

    def reject(self):
        pass  # Cannot cancel this dialog
Exemple #2
0
 def __init__(self, parent=None):
     self.loaded_ruleset = None
     QWidget.__init__(self, parent)
     self.PREFS_OBJECT = JSONConfig('style-transform-rules')
     l = QVBoxLayout(self)
     self.rules_widget = w = Rules(self)
     w.changed.connect(self.changed.emit)
     l.addWidget(w)
     self.h = h = QHBoxLayout()
     l.addLayout(h)
     self.export_button = b = QPushButton(_('E&xport'), self)
     b.setToolTip(_('Export these rules to a file'))
     b.clicked.connect(self.export_rules)
     h.addWidget(b)
     self.import_button = b = QPushButton(_('&Import'), self)
     b.setToolTip(_('Import previously exported rules'))
     b.clicked.connect(self.import_rules)
     h.addWidget(b)
     self.test_button = b = QPushButton(_('&Test rules'), self)
     b.clicked.connect(self.test_rules)
     h.addWidget(b)
     h.addStretch(10)
     self.save_button = b = QPushButton(_('&Save'), self)
     b.setToolTip(_('Save this ruleset for later re-use'))
     b.clicked.connect(self.save_ruleset)
     h.addWidget(b)
     self.export_button = b = QPushButton(_('&Load'), self)
     self.load_menu = QMenu(self)
     b.setMenu(self.load_menu)
     b.setToolTip(_('Load a previously saved ruleset'))
     b.clicked.connect(self.load_ruleset)
     h.addWidget(b)
     self.build_load_menu()
Exemple #3
0
def develop():
    from qt.core import QPainter, QPalette

    from calibre.gui2 import Application
    from calibre_extensions.progress_indicator import SpinAnimator

    class Widget(QWidget):
        def __init__(self):
            QWidget.__init__(self)
            self.a = SpinAnimator(self)
            self.a.updated.connect(self.update)

        def paintEvent(self, ev):
            p = QPainter(self)
            pal = self.palette()
            self.a.draw(p, self.rect(),
                        pal.color(QPalette.ColorRole.WindowText))
            p.end()

    app = Application([])
    d = QDialog()
    d.resize(64, 64)
    l = QVBoxLayout(d)
    w = Widget()
    l.addWidget(w)
    w.a.start()
    d.exec()
    del d
    del app
Exemple #4
0
 def __init__(self, parent):
     QWidget.__init__(self, parent)
     l = QVBoxLayout(parent)
     l.addWidget(self)
     l.setContentsMargins(0, 0, 0, 0)
     l = QFormLayout(self)
     l.setContentsMargins(0, 0, 0, 0)
     l.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)
     self.choices = c = QComboBox()
     c.setMinimumContentsLength(30)
     for text, data in [
             (_('Search for the author on Goodreads'), 'search-goodreads'),
             (_('Search for the author on Amazon'), 'search-amzn'),
             (_('Search for the author in your calibre library'), 'search-calibre'),
             (_('Search for the author on Wikipedia'), 'search-wikipedia'),
             (_('Search for the author on Google Books'), 'search-google'),
             (_('Search for the book on Goodreads'), 'search-goodreads-book'),
             (_('Search for the book on Amazon'), 'search-amzn-book'),
             (_('Search for the book on Google Books'), 'search-google-book'),
             (_('Use a custom search URL'), 'url'),
     ]:
         c.addItem(text, data)
     l.addRow(_('Clicking on &author names should:'), c)
     self.custom_url = u = QLineEdit(self)
     u.setToolTip(_(
         'Enter the URL to search. It should contain the string {0}'
         '\nwhich will be replaced by the author name. For example,'
         '\n{1}').format('{author}', 'https://en.wikipedia.org/w/index.php?search={author}'))
     u.textChanged.connect(self.changed_signal)
     u.setPlaceholderText(_('Enter the URL'))
     c.currentIndexChanged.connect(self.current_changed)
     l.addRow(u)
     self.current_changed()
     c.currentIndexChanged.connect(self.changed_signal)
Exemple #5
0
class DownloadProgress(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setVisible(False)
        self.l = QVBoxLayout(self)
        self.items = {}

    def add_item(self, download_id, filename):
        self.setVisible(True)
        item = DownloadItem(download_id, filename, self)
        self.l.addWidget(item)
        self.items[download_id] = item

    def update_item(self, download_id, done, total):
        item = self.items.get(download_id)
        if item is not None:
            item(done, total)

    def remove_item(self, download_id):
        item = self.items.pop(download_id, None)
        if item is not None:
            self.l.removeWidget(item)
            item.setVisible(False)
            item.setParent(None)
            item.deleteLater()
        if not self.items:
            self.setVisible(False)
Exemple #6
0
 def __init__(self, parent):
     QWidget.__init__(self, parent)
     self.current_result = None
     l = QVBoxLayout(self)
     self.text_browser = tb = Details(self)
     tb.anchorClicked.connect(self.link_clicked)
     l.addWidget(tb)
     self.show_result(None)
Exemple #7
0
    def setup_ui(self):
        self.use_stemmer = us = QCheckBox(_('&Match on related words'))
        us.setChecked(gprefs['browse_annots_use_stemmer'])
        us.setToolTip('<p>' + _(
            'With this option searching for words will also match on any related words (supported in several languages). For'
            ' example, in the English language: <i>correction</i> matches <i>correcting</i> and <i>corrected</i> as well'
        ))
        us.stateChanged.connect(lambda state: gprefs.set(
            'browse_annots_use_stemmer', state != Qt.CheckState.Unchecked))

        l = QVBoxLayout(self)

        self.splitter = s = QSplitter(self)
        l.addWidget(s)
        s.setChildrenCollapsible(False)

        self.browse_panel = bp = BrowsePanel(self)
        bp.open_annotation.connect(self.do_open_annotation)
        bp.show_book.connect(self.show_book)
        bp.delete_requested.connect(self.delete_selected)
        bp.export_requested.connect(self.export_selected)
        bp.edit_annotation.connect(self.edit_annotation)
        s.addWidget(bp)

        self.details_panel = dp = DetailsPanel(self)
        s.addWidget(dp)
        dp.open_annotation.connect(self.do_open_annotation)
        dp.show_book.connect(self.show_book)
        dp.delete_annotation.connect(self.delete_annotation)
        dp.edit_annotation.connect(self.edit_annotation)
        bp.current_result_changed.connect(dp.show_result)

        h = QHBoxLayout()
        l.addLayout(h)
        h.addWidget(us), h.addStretch(10), h.addWidget(self.bb)
        self.delete_button = b = self.bb.addButton(
            _('&Delete all selected'), QDialogButtonBox.ButtonRole.ActionRole)
        b.setToolTip(_('Delete the selected annotations'))
        b.setIcon(QIcon(I('trash.png')))
        b.clicked.connect(self.delete_selected)
        self.export_button = b = self.bb.addButton(
            _('&Export all selected'), QDialogButtonBox.ButtonRole.ActionRole)
        b.setToolTip(_('Export the selected annotations'))
        b.setIcon(QIcon(I('save.png')))
        b.clicked.connect(self.export_selected)
        self.refresh_button = b = RightClickButton(self.bb)
        self.bb.addButton(b, QDialogButtonBox.ButtonRole.ActionRole)
        b.setText(_('&Refresh'))
        b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
        self.refresh_menu = m = QMenu(self)
        m.addAction(_('Rebuild search index')).triggered.connect(self.rebuild)
        b.setMenu(m)
        b.setToolTip(
            _('Refresh annotations in case they have been changed since this window was opened'
              ))
        b.setIcon(QIcon(I('restart.png')))
        b.setPopupMode(QToolButton.ToolButtonPopupMode.DelayedPopup)
        b.clicked.connect(self.refresh)
 def setup_ui(self):
     l = QVBoxLayout(self)
     self.qte = qte = QTextEdit(self)
     qte.setMinimumHeight(400)
     qte.setMinimumWidth(600)
     if self.initial_notes:
         qte.setPlainText(self.initial_notes)
     l.addWidget(qte)
     l.addWidget(self.bb)
Exemple #9
0
 def setup_ui(self):
     self.notes_edit = QPlainTextEdit(self)
     if self.initial_notes:
         self.notes_edit.setPlainText(self.initial_notes)
     self.notes_edit.setMinimumWidth(400)
     self.notes_edit.setMinimumHeight(300)
     l = QVBoxLayout(self)
     l.addWidget(self.notes_edit)
     l.addWidget(self.bb)
Exemple #10
0
class DebugDevice(QDialog):
    def __init__(self, gui, parent=None):
        QDialog.__init__(self, parent)
        self.gui = gui
        self._layout = QVBoxLayout(self)
        self.setLayout(self._layout)
        self.log = QPlainTextEdit(self)
        self._layout.addWidget(self.log)
        self.log.setPlainText(
            _('Getting debug information, please wait') + '...')
        self.copy = QPushButton(_('Copy to &clipboard'))
        self.copy.setDefault(True)
        self.setWindowTitle(_('Debug device detection'))
        self.setWindowIcon(QIcon(I('debug.png')))
        self.copy.clicked.connect(self.copy_to_clipboard)
        self.ok = QPushButton('&OK')
        self.ok.setAutoDefault(False)
        self.ok.clicked.connect(self.accept)
        self.bbox = QDialogButtonBox(self)
        self.bbox.addButton(self.copy, QDialogButtonBox.ButtonRole.ActionRole)
        self.bbox.addButton(self.ok, QDialogButtonBox.ButtonRole.AcceptRole)
        self._layout.addWidget(self.bbox)
        self.resize(750, 500)
        self.bbox.setEnabled(False)
        QTimer.singleShot(1000, self.debug)

    def debug(self):
        if self.gui.device_manager.is_device_connected:
            error_dialog(
                self,
                _('Device already detected'),
                _('A device (%s) is already detected by calibre.'
                  ' If you wish to debug the detection of another device'
                  ', first disconnect this device.') %
                self.gui.device_manager.connected_device.get_gui_name(),
                show=True)
            self.bbox.setEnabled(True)
            return
        self.gui.debug_detection(self)

    def __call__(self, job):
        if not self.isVisible():
            return
        self.bbox.setEnabled(True)
        if job.failed:
            return error_dialog(
                self,
                _('Debugging failed'),
                _('Running debug device detection failed. Click Show '
                  'Details for more information.'),
                det_msg=job.details,
                show=True)
        self.log.setPlainText(job.result)

    def copy_to_clipboard(self):
        QApplication.clipboard().setText(self.log.toPlainText())
Exemple #11
0
 def setup_ui(self):
     l = QVBoxLayout(self)
     self.qte = qte = QTextEdit(self)
     qte.setMinimumHeight(400)
     qte.setMinimumWidth(600)
     if self.initial_notes:
         qte.setPlainText(self.initial_notes)
         qte.moveCursor(QTextCursor.MoveOperation.End)
     l.addWidget(qte)
     l.addWidget(self.bb)
Exemple #12
0
 def __init__(self, parent):
     QWidget.__init__(self, parent)
     l = QVBoxLayout()
     self.setLayout(l)
     l.addStretch(10)
     self.pi = ProgressIndicator(self, 128)
     l.addWidget(self.pi, alignment=Qt.AlignmentFlag.AlignHCenter)
     self.dummy = QLabel('<h2>\xa0')
     l.addSpacing(10)
     l.addWidget(self.dummy, alignment=Qt.AlignmentFlag.AlignHCenter)
     l.addStretch(10)
     self.text = _('Calculating differences, please wait...')
Exemple #13
0
class DBCheck(QDialog):  # {{{

    update_msg = pyqtSignal(object)

    def __init__(self, parent, db):
        QDialog.__init__(self, parent)
        self.l = QVBoxLayout()
        self.setLayout(self.l)
        self.l1 = QLabel(
            _('Vacuuming database to improve performance.') + ' ' +
            _('This will take a while, please wait...'))
        self.setWindowTitle(_('Vacuuming...'))
        self.l1.setWordWrap(True)
        self.l.addWidget(self.l1)
        self.msg = QLabel('')
        self.update_msg.connect(self.msg.setText,
                                type=Qt.ConnectionType.QueuedConnection)
        self.l.addWidget(self.msg)
        self.msg.setWordWrap(True)
        self.resize(self.sizeHint() + QSize(100, 50))
        self.error = None
        self.db = db.new_api
        self.rejected = False

    def start(self):
        t = self.thread = Thread(target=self.vacuum)
        t.daemon = True
        t.start()
        QTimer.singleShot(100, self.check)
        self.exec_()

    def vacuum(self):
        try:
            self.db.vacuum()
        except Exception as e:
            import traceback
            self.error = (as_unicode(e), traceback.format_exc())

    def reject(self):
        self.rejected = True
        return QDialog.reject(self)

    def check(self):
        if self.rejected:
            return
        if self.thread.is_alive():
            QTimer.singleShot(100, self.check)
        else:
            self.accept()

    def break_cycles(self):
        self.db = self.thread = None
    def __init__(self, parent):
        QDialog.__init__(self, parent)

        self.setWindowTitle(_('Choose stores'))

        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        v = QVBoxLayout(self)
        self.config_widget = StoreChooserWidget()
        v.addWidget(self.config_widget)
        v.addWidget(button_box)

        self.resize(800, 600)
Exemple #15
0
 def __init__(self, pa, parent):
     QDialog.__init__(self, parent)
     self.test_func = parent.test_email_settings
     self.setWindowTitle(_("Test email settings"))
     self.setWindowIcon(QIcon(I('config.ui')))
     l = QVBoxLayout(self)
     opts = smtp_prefs().parse()
     self.from_ = la = QLabel(_("Send test mail from %s to:") % opts.from_)
     l.addWidget(la)
     self.to = le = QLineEdit(self)
     if pa:
         self.to.setText(pa)
     self.test_button = b = QPushButton(_('&Test'), self)
     b.clicked.connect(self.start_test)
     self.test_done.connect(self.on_test_done,
                            type=Qt.ConnectionType.QueuedConnection)
     self.h = h = QHBoxLayout()
     h.addWidget(le), h.addWidget(b)
     l.addLayout(h)
     if opts.relay_host:
         self.la = la = QLabel(
             _('Using: %(un)s:%(pw)s@%(host)s:%(port)s and %(enc)s encryption'
               ) % dict(un=opts.relay_username,
                        pw=from_hex_unicode(opts.relay_password),
                        host=opts.relay_host,
                        port=opts.relay_port,
                        enc=opts.encryption))
         l.addWidget(la)
     self.log = QPlainTextEdit(self)
     l.addWidget(self.log)
     self.bb = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
     bb.rejected.connect(self.reject), bb.accepted.connect(self.accept)
     l.addWidget(bb)
Exemple #16
0
 def __init__(self, parent):
     QWidget.__init__(self, parent)
     l = QVBoxLayout()
     self.setLayout(l)
     l.addStretch(10)
     self.pi = ProgressIndicator(self, 128)
     l.addWidget(self.pi, alignment=Qt.AlignmentFlag.AlignHCenter)
     self.dummy = QLabel('<h2>\xa0')
     l.addSpacing(10)
     l.addWidget(self.dummy, alignment=Qt.AlignmentFlag.AlignHCenter)
     l.addStretch(10)
     self.setVisible(False)
     self.text = ''
     self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
Exemple #17
0
    def setup_ui(self):
        from calibre.gui2.preferences.look_feel import (DisplayedFields,
                                                        move_field_down,
                                                        move_field_up)
        self.l = QVBoxLayout(self)
        self.field_display_order = fdo = QListView(self)
        self.model = DisplayedFields(self.db,
                                     fdo,
                                     pref_name='popup_book_display_fields')
        self.model.initialize()
        fdo.setModel(self.model)
        fdo.setAlternatingRowColors(True)
        del self.db
        self.l.addWidget(QLabel(_('Select displayed metadata')))
        h = QHBoxLayout()
        h.addWidget(fdo)
        v = QVBoxLayout()
        self.mub = b = QToolButton(self)
        connect_lambda(b.clicked, self,
                       lambda self: move_field_up(fdo, self.model))
        b.setIcon(QIcon(I('arrow-up.png')))
        b.setToolTip(_('Move the selected field up'))
        v.addWidget(b), v.addStretch(10)
        self.mud = b = QToolButton(self)
        b.setIcon(QIcon(I('arrow-down.png')))
        b.setToolTip(_('Move the selected field down'))
        connect_lambda(b.clicked, self,
                       lambda self: move_field_down(fdo, self.model))
        v.addWidget(b)
        h.addLayout(v)

        self.l.addLayout(h)
        self.l.addWidget(
            QLabel('<p>' + _(
                'Note that <b>comments</b> will always be displayed at the end, regardless of the order you assign here'
            )))

        b = self.bb.addButton(_('Restore &defaults'),
                              QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.restore_defaults)
        b = self.bb.addButton(_('Select &all'),
                              QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.select_all)
        b = self.bb.addButton(_('Select &none'),
                              QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.select_none)
        self.l.addWidget(self.bb)
        self.setMinimumHeight(500)
Exemple #18
0
 def show_devtools(self):
     if not hasattr(self, '_devtools_page'):
         self._devtools_page = QWebEnginePage()
         self._devtools_view = QWebEngineView(self)
         self._devtools_view.setPage(self._devtools_page)
         self._page.setDevToolsPage(self._devtools_page)
         self._devtools_dialog = d = QDialog(self)
         d.setWindowTitle('Inspect Lookup page')
         v = QVBoxLayout(d)
         v.addWidget(self._devtools_view)
         d.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
         d.bb.rejected.connect(d.reject)
         v.addWidget(d.bb)
         d.resize(QSize(800, 600))
         d.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, False)
     self._devtools_dialog.show()
     self._page.triggerAction(QWebEnginePage.WebAction.InspectElement)
Exemple #19
0
class Browser(QScrollArea):  # {{{

    show_plugin = pyqtSignal(object)

    def __init__(self, parent=None):
        QScrollArea.__init__(self, parent)
        self.setWidgetResizable(True)

        category_map, category_names = {}, {}
        for plugin in preferences_plugins():
            if plugin.category not in category_map:
                category_map[plugin.category] = plugin.category_order
            if category_map[plugin.category] < plugin.category_order:
                category_map[plugin.category] = plugin.category_order
            if plugin.category not in category_names:
                category_names[plugin.category] = (plugin.gui_category
                                                   if plugin.gui_category else
                                                   plugin.category)

        self.category_names = category_names

        categories = list(category_map.keys())
        categories.sort(key=lambda x: category_map[x])

        self.category_map = OrderedDict()
        for c in categories:
            self.category_map[c] = []

        for plugin in preferences_plugins():
            self.category_map[plugin.category].append(plugin)

        for plugins in self.category_map.values():
            plugins.sort(key=lambda x: x.name_order)

        self.widgets = []
        self._layout = QVBoxLayout()
        self.container = QWidget(self)
        self.container.setLayout(self._layout)
        self.setWidget(self.container)

        for name, plugins in self.category_map.items():
            w = Category(name, plugins, self.category_names[name], parent=self)
            self.widgets.append(w)
            self._layout.addWidget(w)
            w.plugin_activated.connect(self.show_plugin.emit)
        self._layout.addStretch(1)
    def setup_ui(self):
        self.use_stemmer = us = QCheckBox(_('Match on related English words'))
        us.setChecked(gprefs['browse_annots_use_stemmer'])
        us.setToolTip('<p>' + _(
            'With this option searching for words will also match on any related English words. For'
            ' example: <i>correction</i> matches <i>correcting</i> and <i>corrected</i> as well'
        ))
        us.stateChanged.connect(lambda state: gprefs.set(
            'browse_annots_use_stemmer', state != Qt.CheckState.Unchecked))

        l = QVBoxLayout(self)

        self.splitter = s = QSplitter(self)
        l.addWidget(s)
        s.setChildrenCollapsible(False)

        self.browse_panel = bp = BrowsePanel(self)
        bp.open_annotation.connect(self.do_open_annotation)
        bp.show_book.connect(self.show_book)
        bp.delete_requested.connect(self.delete_selected)
        bp.export_requested.connect(self.export_selected)
        bp.edit_annotation.connect(self.edit_annotation)
        s.addWidget(bp)

        self.details_panel = dp = DetailsPanel(self)
        s.addWidget(dp)
        dp.open_annotation.connect(self.do_open_annotation)
        dp.show_book.connect(self.show_book)
        dp.delete_annotation.connect(self.delete_annotation)
        dp.edit_annotation.connect(self.edit_annotation)
        bp.current_result_changed.connect(dp.show_result)

        h = QHBoxLayout()
        l.addLayout(h)
        h.addWidget(us), h.addStretch(10), h.addWidget(self.bb)
        self.delete_button = b = self.bb.addButton(
            _('Delete all selected'), QDialogButtonBox.ButtonRole.ActionRole)
        b.setToolTip(_('Delete the selected annotations'))
        b.setIcon(QIcon(I('trash.png')))
        b.clicked.connect(self.delete_selected)
        self.export_button = b = self.bb.addButton(
            _('Export all selected'), QDialogButtonBox.ButtonRole.ActionRole)
        b.setToolTip(_('Export the selected annotations'))
        b.setIcon(QIcon(I('save.png')))
        b.clicked.connect(self.export_selected)
Exemple #21
0
    def do_config(self):
        # Save values that need to be synced between the dialog and the
        # search widget.
        self.config['open_external'] = self.open_external.isChecked()

        # Create the config dialog. It's going to put two config widgets
        # into a QTabWidget for displaying all of the settings.
        d = QDialog(self)
        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
        v = QVBoxLayout(d)
        button_box.accepted.connect(d.accept)
        button_box.rejected.connect(d.reject)
        d.setWindowTitle(_('Customize Get books search'))

        tab_widget = QTabWidget(d)
        v.addWidget(tab_widget)
        v.addWidget(button_box)

        chooser_config_widget = StoreChooserWidget()
        search_config_widget = StoreConfigWidget(self.config)

        tab_widget.addTab(chooser_config_widget, _('Choose s&tores'))
        tab_widget.addTab(search_config_widget, _('Configure s&earch'))

        # Restore dialog state.
        geometry = self.config.get('config_dialog_geometry', None)
        if geometry:
            QApplication.instance().safe_restore_geometry(d, geometry)
        else:
            d.resize(800, 600)
        tab_index = self.config.get('config_dialog_tab_index', 0)
        tab_index = min(tab_index, tab_widget.count() - 1)
        tab_widget.setCurrentIndex(tab_index)

        d.exec()

        # Save dialog state.
        self.config['config_dialog_geometry'] = bytearray(d.saveGeometry())
        self.config['config_dialog_tab_index'] = tab_widget.currentIndex()

        search_config_widget.save_settings()
        self.config_changed()
        self.gui.load_store_plugins()
        self.setup_store_checks()
Exemple #22
0
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.use_stemmer = parent.use_stemmer
        self.current_query = None
        l = QVBoxLayout(self)

        h = QHBoxLayout()
        l.addLayout(h)
        self.search_box = sb = SearchBox(self)
        sb.initialize('library-annotations-browser-search-box')
        sb.cleared.connect(self.cleared,
                           type=Qt.ConnectionType.QueuedConnection)
        sb.lineEdit().returnPressed.connect(self.show_next)
        sb.lineEdit().setPlaceholderText(_('Enter words to search for'))
        h.addWidget(sb)

        self.next_button = nb = QToolButton(self)
        h.addWidget(nb)
        nb.setFocusPolicy(Qt.FocusPolicy.NoFocus)
        nb.setIcon(QIcon(I('arrow-down.png')))
        nb.clicked.connect(self.show_next)
        nb.setToolTip(_('Find next match'))

        self.prev_button = nb = QToolButton(self)
        h.addWidget(nb)
        nb.setFocusPolicy(Qt.FocusPolicy.NoFocus)
        nb.setIcon(QIcon(I('arrow-up.png')))
        nb.clicked.connect(self.show_previous)
        nb.setToolTip(_('Find previous match'))

        self.restrictions = rs = Restrictions(self)
        rs.restrictions_changed.connect(self.effective_query_changed)
        self.use_stemmer.stateChanged.connect(self.effective_query_changed)
        l.addWidget(rs)

        self.results_list = rl = ResultsList(self)
        rl.current_result_changed.connect(self.current_result_changed)
        rl.open_annotation.connect(self.open_annotation)
        rl.show_book.connect(self.show_book)
        rl.edit_annotation.connect(self.edit_annotation)
        rl.delete_requested.connect(self.delete_requested)
        rl.export_requested.connect(self.export_requested)
        l.addWidget(rl)
Exemple #23
0
class Wizard(QDialog):

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.resize(440, 480)
        self.verticalLayout = QVBoxLayout(self)
        self.widget = WizardWidget(self)
        self.verticalLayout.addWidget(self.widget)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.StandardButton.Cancel|QDialogButtonBox.StandardButton.Ok)
        self.verticalLayout.addWidget(self.buttonBox)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.setModal(Qt.WindowModality.WindowModal)

    @property
    def xpath(self):
        return self.widget.xpath
Exemple #24
0
class ChoosePluginToolbarsDialog(QDialog):
    def __init__(self, parent, plugin, locations):
        QDialog.__init__(self, parent)
        self.locations = locations

        self.setWindowTitle(_('Add "%s" to toolbars or menus') % plugin.name)

        self._layout = QVBoxLayout(self)
        self.setLayout(self._layout)

        self._header_label = QLabel(
            _('Select the toolbars and/or menus to add <b>%s</b> to:') %
            plugin.name)
        self._layout.addWidget(self._header_label)

        self._locations_list = QListWidget(self)
        self._locations_list.setSelectionMode(
            QAbstractItemView.SelectionMode.MultiSelection)
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred,
                                 QSizePolicy.Policy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        self._locations_list.setSizePolicy(sizePolicy)
        for key, text in locations:
            self._locations_list.addItem(text)
            if key in {'toolbar', 'toolbar-device'}:
                self._locations_list.item(self._locations_list.count() -
                                          1).setSelected(True)
        self._layout.addWidget(self._locations_list)

        self._footer_label = QLabel(
            _('You can also customise the plugin locations '
              'using <b>Preferences -> Interface -> Toolbars</b>'))
        self._layout.addWidget(self._footer_label)

        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok
                                      | QDialogButtonBox.StandardButton.Cancel)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        self._layout.addWidget(button_box)
        self.resize(self.sizeHint())

    def selected_locations(self):
        selected = []
        for row in self._locations_list.selectionModel().selectedRows():
            selected.append(self.locations[row.row()])
        return selected
Exemple #25
0
    def do_user_config(self, parent=None):
        '''
        This method shows a configuration dialog for this plugin. It returns
        True if the user clicks OK, False otherwise. The changes are
        automatically applied.
        '''
        from qt.core import (QDialog, QDialogButtonBox, QVBoxLayout, QLabel,
                             Qt, QLineEdit, QCheckBox)

        config_dialog = QDialog(parent)
        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok
                                      | QDialogButtonBox.StandardButton.Cancel)
        v = QVBoxLayout(config_dialog)

        def size_dialog():
            config_dialog.resize(config_dialog.sizeHint())

        button_box.accepted.connect(config_dialog.accept)
        button_box.rejected.connect(config_dialog.reject)
        config_dialog.setWindowTitle(_('Customize') + ' ' + self.name)
        from calibre.customize.ui import (plugin_customization,
                                          customize_plugin)
        help_text = self.customization_help(gui=True)
        help_text = QLabel(help_text, config_dialog)
        help_text.setWordWrap(True)
        help_text.setTextInteractionFlags(
            Qt.TextInteractionFlag.LinksAccessibleByMouse
            | Qt.TextInteractionFlag.LinksAccessibleByKeyboard)
        help_text.setOpenExternalLinks(True)
        v.addWidget(help_text)
        bf = QCheckBox(_('Add linked files in breadth first order'))
        bf.setToolTip(
            _('Normally, when following links in HTML files'
              ' calibre does it depth first, i.e. if file A links to B and '
              ' C, but B links to D, the files are added in the order A, B, D, C. '
              ' With this option, they will instead be added as A, B, C, D'))
        sc = plugin_customization(self)
        if not sc:
            sc = ''
        sc = sc.strip()
        enc = sc.partition('|')[0]
        bfs = sc.partition('|')[-1]
        bf.setChecked(bfs == 'bf')
        sc = QLineEdit(enc, config_dialog)
        v.addWidget(sc)
        v.addWidget(bf)
        v.addWidget(button_box)
        size_dialog()
        config_dialog.exec()

        if config_dialog.result() == QDialog.DialogCode.Accepted:
            sc = str(sc.text()).strip()
            if bf.isChecked():
                sc += '|bf'
            customize_plugin(self, sc)

        return config_dialog.result()
class SelectFormats(QDialog):
    def __init__(self,
                 fmt_count,
                 msg,
                 single=False,
                 parent=None,
                 exclude=False):
        QDialog.__init__(self, parent)
        self._l = QVBoxLayout(self)
        self.single_fmt = single
        self.setLayout(self._l)
        self.setWindowTitle(_('Choose formats'))
        self._m = QLabel(msg)
        self._m.setWordWrap(True)
        self._l.addWidget(self._m)
        self.formats = Formats(fmt_count)
        self.fview = QListView(self)
        self.fview.doubleClicked.connect(
            self.double_clicked, type=Qt.ConnectionType.QueuedConnection)
        if exclude:
            if QApplication.instance().is_dark_theme:
                sheet = 'background-color: #DAA520; color: black'
            else:
                sheet = 'background-color: #fae7b5'
            self.fview.setStyleSheet('QListView { %s }' % sheet)
        self._l.addWidget(self.fview)
        self.fview.setModel(self.formats)
        self.fview.setSelectionMode(
            QAbstractItemView.SelectionMode.SingleSelection
            if single else QAbstractItemView.SelectionMode.MultiSelection)
        self.bbox = \
        QDialogButtonBox(QDialogButtonBox.StandardButton.Ok|QDialogButtonBox.StandardButton.Cancel,
                Qt.Orientation.Horizontal, self)
        self._l.addWidget(self.bbox)
        self.bbox.accepted.connect(self.accept)
        self.bbox.rejected.connect(self.reject)
        self.fview.setIconSize(QSize(48, 48))
        self.fview.setSpacing(2)

        self.resize(350, 500)
        self.selected_formats = set()

    def accept(self, *args):
        for idx in self.fview.selectedIndexes():
            self.selected_formats.add(self.formats.fmt(idx))
        QDialog.accept(self, *args)

    def double_clicked(self, index):
        if self.single_fmt:
            self.accept()
Exemple #27
0
class Category(QWidget):  # {{{

    plugin_activated = pyqtSignal(object)

    def __init__(self, name, plugins, gui_name, parent=None):
        QWidget.__init__(self, parent)
        self._layout = QVBoxLayout()
        self.setLayout(self._layout)
        self.label = QLabel(gui_name)
        self.sep = QFrame(self)
        self.bf = QFont()
        self.bf.setBold(True)
        self.label.setFont(self.bf)
        self.sep.setFrameShape(QFrame.Shape.HLine)
        self._layout.addWidget(self.label)
        self._layout.addWidget(self.sep)

        self.plugins = plugins

        self.bar = QToolBar(self)
        self.bar.setStyleSheet('QToolBar { border: none; background: none }')
        lh = QApplication.instance().line_height
        self.bar.setIconSize(QSize(2 * lh, 2 * lh))
        self.bar.setMovable(False)
        self.bar.setFloatable(False)
        self.bar.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextUnderIcon)
        self._layout.addWidget(self.bar)
        self.actions = []
        for p in plugins:
            target = partial(self.triggered, p)
            ac = self.bar.addAction(QIcon(p.icon),
                                    p.gui_name.replace('&', '&&'), target)
            ac.setToolTip(textwrap.fill(p.description))
            ac.setWhatsThis(textwrap.fill(p.description))
            ac.setStatusTip(p.description)
            self.actions.append(ac)
            w = self.bar.widgetForAction(ac)
            w.setCursor(Qt.CursorShape.PointingHandCursor)
            if hasattr(w, 'setAutoRaise'):
                w.setAutoRaise(True)
            w.setMinimumWidth(100)

    def triggered(self, plugin, *args):
        self.plugin_activated.emit(plugin)
class Tab1Config(DeviceConfigTab):  # {{{
    def __init__(self, parent, device):
        super().__init__(parent)

        self.l = QVBoxLayout(self)
        self.setLayout(self.l)

        self.collections_options = CollectionsGroupBox(self, device)
        self.l.addWidget(self.collections_options)
        self.addDeviceWidget(self.collections_options)

        self.covers_options = CoversGroupBox(self, device)
        self.l.addWidget(self.covers_options)
        self.addDeviceWidget(self.covers_options)

        self.book_uploads_options = BookUploadsGroupBox(self, device)
        self.l.addWidget(self.book_uploads_options)
        self.addDeviceWidget(self.book_uploads_options)

        self.l.addStretch()
Exemple #29
0
 def __init__(self, parent, duplicates, loc):
     QDialog.__init__(self, parent)
     l = QVBoxLayout()
     self.setLayout(l)
     self.la = la = QLabel(
         _('Books with the same, title, author and language as the following already exist in the library %s.'
           ' Select which books you want copied anyway.') %
         os.path.basename(loc))
     la.setWordWrap(True)
     l.addWidget(la)
     self.setWindowTitle(_('Duplicate books'))
     self.books = QListWidget(self)
     self.items = []
     for book_id, (title, authors) in iteritems(duplicates):
         i = QListWidgetItem(
             _('{0} by {1}').format(title, ' & '.join(authors[:3])),
             self.books)
         i.setData(Qt.ItemDataRole.UserRole, book_id)
         i.setFlags(Qt.ItemFlag.ItemIsUserCheckable
                    | Qt.ItemFlag.ItemIsEnabled)
         i.setCheckState(Qt.CheckState.Checked)
         self.items.append(i)
     l.addWidget(self.books)
     self.bb = bb = QDialogButtonBox(
         QDialogButtonBox.StandardButton.Ok
         | QDialogButtonBox.StandardButton.Cancel)
     bb.accepted.connect(self.accept)
     bb.rejected.connect(self.reject)
     self.a = b = bb.addButton(_('Select &all'),
                               QDialogButtonBox.ButtonRole.ActionRole)
     b.clicked.connect(self.select_all), b.setIcon(QIcon(I('plus.png')))
     self.n = b = bb.addButton(_('Select &none'),
                               QDialogButtonBox.ButtonRole.ActionRole)
     b.clicked.connect(self.select_none), b.setIcon(QIcon(I('minus.png')))
     self.ctc = b = bb.addButton(_('&Copy to clipboard'),
                                 QDialogButtonBox.ButtonRole.ActionRole)
     b.clicked.connect(self.copy_to_clipboard), b.setIcon(
         QIcon(I('edit-copy.png')))
     l.addWidget(bb)
     self.resize(600, 400)
class Tab2Config(DeviceConfigTab):  # {{{
    def __init__(self, parent, device):
        super().__init__(parent)

        self.l = QVBoxLayout(self)
        self.setLayout(self.l)

        self.metadata_options = MetadataGroupBox(self, device)
        self.l.addWidget(self.metadata_options)
        self.addDeviceWidget(self.metadata_options)

        self.device_list_options = DeviceListGroupBox(self, device)
        self.l.addWidget(self.device_list_options)
        self.addDeviceWidget(self.device_list_options)

        self.advanced_options = AdvancedGroupBox(self, device)
        self.l.addWidget(self.advanced_options)
        self.addDeviceWidget(self.advanced_options)

        self.l.addStretch()

    def validate(self):
        return self.metadata_options.validate()