示例#1
0
 def __init__(self, parent):
     self.restrict_to_book_ids = frozenset()
     QWidget.__init__(self, parent)
     v = QVBoxLayout(self)
     v.setContentsMargins(0, 0, 0, 0)
     h = QHBoxLayout()
     h.setContentsMargins(0, 0, 0, 0)
     v.addLayout(h)
     self.rla = QLabel(_('Restrict to') + ': ')
     h.addWidget(self.rla)
     la = QLabel(_('Types:'))
     h.addWidget(la)
     self.types_box = tb = QComboBox(self)
     tb.la = la
     tb.currentIndexChanged.connect(self.restrictions_changed)
     connect_lambda(tb.currentIndexChanged, tb, lambda tb: gprefs.set('browse_annots_restrict_to_type', tb.currentData()))
     la.setBuddy(tb)
     tb.setToolTip(_('Show only annotations of the specified type'))
     h.addWidget(tb)
     la = QLabel(_('User:'******'browse_annots_restrict_to_user', ub.currentData()))
     la.setBuddy(ub)
     ub.setToolTip(_('Show only annotations created by the specified user'))
     h.addWidget(ub)
     h.addStretch(10)
     h = QHBoxLayout()
     self.restrict_to_books_cb = cb = QCheckBox('')
     self.update_book_restrictions_text()
     cb.setToolTip(_('Only show annotations from books that have been selected in the calibre library'))
     cb.setChecked(bool(gprefs.get('show_annots_from_selected_books_only', False)))
     cb.stateChanged.connect(self.show_only_selected_changed)
     h.addWidget(cb)
     v.addLayout(h)
示例#2
0
    def setupUi(self, *a):
        Ui_Form.setupUi(self, *a)
        v = self.page_margins_box.v = QVBoxLayout(self.page_margins_box)
        self.opt_pdf_use_document_margins = c = QCheckBox(_('Use page margins from the &document being converted'))
        v.addWidget(c)
        h = self.page_margins_box.h = QHBoxLayout()
        l = self.page_margins_box.l = QFormLayout()
        r = self.page_margins_box.r = QFormLayout()
        h.addLayout(l), h.addLayout(r)
        v.addLayout(h)

        def margin(which):
            w = QDoubleSpinBox(self)
            w.setRange(-100, 500), w.setSuffix(' pt'), w.setDecimals(1)
            setattr(self, 'opt_pdf_page_margin_' + which, w)
            return w

        l.addRow(_('&Left:'), margin('left'))
        l.addRow(_('&Right:'), margin('right'))
        r.addRow(_('&Top:'), margin('top'))
        r.addRow(_('&Bottom:'), margin('bottom'))
        self.opt_use_profile_size.toggled.connect(self.profile_size_toggled)
示例#3
0
    def setup_ui(self):
        self.l = l = QVBoxLayout(self)
        self.plist = pl = QListWidget(self)
        pl.setIconSize(QSize(48, 48)), pl.setSpacing(5)
        l.addWidget(pl)

        self.bb.clear(), self.bb.setStandardButtons(
            QDialogButtonBox.StandardButton.Close)
        self.rb = b = self.bb.addButton(_('&Remove'),
                                        QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.remove), b.setIcon(QIcon(I('list_remove.png')))
        self.cb = b = self.bb.addButton(_('Change &icon'),
                                        QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.change_icon), b.setIcon(
            QIcon(I('icon_choose.png')))
        self.cb = b = self.bb.addButton(_('Change &name'),
                                        QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.change_name), b.setIcon(QIcon(
            I('modified.png')))
        l.addWidget(self.bb)

        self.populate()
    def __init__(self, gui, error):
        QDialog.__init__(self, gui)
        self.l = l = QVBoxLayout()
        self.setLayout(l)
        self.la = la = QLabel('<p>'+
            _('You are trying to send books into the <b>%s</b> folder. This '
              'folder is currently ignored by calibre when scanning the '
              'device. You have to tell calibre you want this folder scanned '
              'in order to be able to send books to it. Click the '
              '<b>Configure</b> button below to send books to it.')%error.folder)
        la.setWordWrap(True)
        la.setMinimumWidth(500)
        l.addWidget(la)
        self.bb = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
        self.b = bb.addButton(_('Configure'), QDialogButtonBox.ButtonRole.AcceptRole)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        l.addWidget(bb)
        self.setWindowTitle(_('Cannot send to %s')%error.folder)
        self.setWindowIcon(QIcon(I('dialog_error.png')))

        self.resize(self.sizeHint())
示例#5
0
 def change_builtin(self):
     d = QDialog(self)
     lw = QListWidget(d)
     for (trigger, syntaxes), snip in iteritems(builtin_snippets):
         snip = copy.deepcopy(snip)
         snip['trigger'], snip['syntaxes'] = trigger, syntaxes
         i = QListWidgetItem(self.snip_to_text(snip), lw)
         i.setData(Qt.ItemDataRole.UserRole, snip)
     d.l = l = QVBoxLayout(d)
     l.addWidget(QLabel(_('Choose the built-in snippet to modify:')))
     l.addWidget(lw)
     lw.itemDoubleClicked.connect(d.accept)
     d.bb = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok
                                  | QDialogButtonBox.StandardButton.Cancel)
     l.addWidget(bb)
     bb.accepted.connect(d.accept), bb.rejected.connect(d.reject)
     if d.exec_() == QDialog.DialogCode.Accepted and lw.currentItem(
     ) is not None:
         self.stack.setCurrentIndex(1)
         self.edit_snip.apply_snip(lw.currentItem().data(
             Qt.ItemDataRole.UserRole),
                                   creating_snippet=True)
示例#6
0
 def setup_ui(self):
     from calibre.gui2.tweak_book.editor.text import TextEdit
     self.l = l = QVBoxLayout(self)
     self.bb.setStandardButtons(QDialogButtonBox.StandardButton.Close)
     self.la = la = QLabel(self.LABEL)
     l.addWidget(la)
     self.css = t = TextEdit(self)
     t.load_text('', self.SYNTAX)
     la.setBuddy(t)
     c = t.textCursor()
     c.movePosition(QTextCursor.MoveOperation.End)
     t.setTextCursor(c)
     self.h = h = QHBoxLayout()
     l.addLayout(h)
     h.addWidget(t)
     self.test_button = b = QPushButton(_('&Test'), self)
     b.clicked.connect(self.do_test)
     h.addWidget(b)
     self.result = la = TextEdit(self)
     la.setReadOnly(True)
     l.addWidget(la)
     l.addWidget(self.bb)
示例#7
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.l = l = QVBoxLayout(self)
        self.h = h = QHBoxLayout()

        self.la = la = QLabel(self.MSG)
        la.setWordWrap(True)
        l.addWidget(la)
        l.addLayout(h)
        english_sentence = '{preamble} {match_type}'
        sentence = _('{preamble} {match_type}')
        if set(sentence.split()) != set(english_sentence.split()):
            sentence = english_sentence
        parts = sentence.split()
        for clause in parts:
            if clause == '{preamble}':
                self.preamble = w = QLabel(_('If the tag'))
            elif clause == '{match_type}':
                self.match_type = w = QComboBox(self)
                for action, m in MATCH_TYPE_MAP.items():
                    w.addItem(m.text, action)
                w.currentIndexChanged.connect(self.update_state)
            h.addWidget(w)
            if clause is not parts[-1]:
                h.addWidget(QLabel('\xa0'))
        h.addStretch(1)
        self.generic_query = gq = GenericEdit(self)
        self.css_query = cq = CSSEdit(self)
        self.xpath_query = xq = XPathEdit(self, object_name='html_transform_rules_xpath', show_msg=False)
        l.addWidget(gq), l.addWidget(cq), l.addWidget(xq)

        self.thenl = QLabel(_('Then:'))
        l.addWidget(self.thenl)
        self.actions = a = ActionsContainer(self)
        l.addWidget(a)
        self.add_button = b = QPushButton(QIcon(I('plus.png')), _('Add another action'))
        b.clicked.connect(self.actions.new_action)
        l.addWidget(b)
        self.update_state()
示例#8
0
    def setup_ui(self):
        from calibre.gui2.tweak_book.templates import DEFAULT_TEMPLATES
        from calibre.gui2.tweak_book.editor.text import TextEdit
        # Cannot use QFormLayout as it does not play nice with TextEdit on windows
        self.l = l = QVBoxLayout(self)

        self.syntaxes = s = QComboBox(self)
        s.addItems(sorted(DEFAULT_TEMPLATES))
        s.setCurrentIndex(s.findText('html'))
        h = QHBoxLayout()
        l.addLayout(h)
        la = QLabel(_('Choose the &type of template to edit:'))
        la.setBuddy(s)
        h.addWidget(la), h.addWidget(s), h.addStretch(10)
        s.currentIndexChanged.connect(self.show_template)

        self.helpl = la = QLabel(_(
            'The variables {0} and {1} will be replaced with the title and author of the book. {2}'
            ' is where the cursor will be positioned. If you want to include braces in your template,'
            ' for example for CSS rules, you have to escape them, like this: {3}').format(*['<code>%s</code>'%x for x in
                ['{TITLE}', '{AUTHOR}', '%CURSOR%', 'body {{ color: red }}']]))
        la.setWordWrap(True)
        l.addWidget(la)

        self.save_timer = t = QTimer(self)
        t.setSingleShot(True), t.setInterval(100)
        t.timeout.connect(self._save_syntax)

        self.editor = e = TextEdit(self)
        l.addWidget(e)
        e.textChanged.connect(self.save_syntax)

        self.show_template()

        self.bb.clear()
        self.bb.addButton(QDialogButtonBox.StandardButton.Close)
        self.rd = b = self.bb.addButton(QDialogButtonBox.StandardButton.RestoreDefaults)
        b.clicked.connect(self.restore_defaults)
        l.addWidget(self.bb)
示例#9
0
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()
示例#10
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)
示例#11
0
    def __init__(self, log, parent=None):
        QWidget.__init__(self, parent)
        self.log = log
        self.abort = Event()
        self.caches = {}

        self.l = l = QVBoxLayout(self)

        names = ['<b>'+p.name+'</b>' for p in metadata_plugins(['identify']) if
                p.is_configured()]
        self.top = QLabel('<p>'+_('calibre is downloading metadata from: ') +
            ', '.join(names))
        self.top.setWordWrap(True)
        l.addWidget(self.top)

        self.splitter = s = QSplitter(self)
        s.setChildrenCollapsible(False)
        l.addWidget(s, 100)
        self.results_view = ResultsView(self)
        self.results_view.book_selected.connect(self.emit_book_selected)
        self.get_result = self.results_view.get_result
        s.addWidget(self.results_view)

        self.comments_view = Comments(self)
        s.addWidget(self.comments_view)
        s.setStretchFactor(0, 2)
        s.setStretchFactor(1, 1)

        self.results_view.show_details_signal.connect(self.comments_view.show_data)

        self.query = QLabel('download starting...')
        self.query.setWordWrap(True)
        l.addWidget(self.query)

        self.comments_view.show_wait()
        state = gprefs.get('metadata-download-identify-widget-splitter-state')
        if state is not None:
            s.restoreState(state)
    def __init__(self, names, txt, parent=None):
        QDialog.__init__(self, parent)
        self.l = l = QVBoxLayout(self)
        self.setLayout(l)

        self.la = la = QLabel(_('Create a Virtual library based on %s') % txt)
        l.addWidget(la)

        self.filter = f = QLineEdit(self)
        f.setPlaceholderText(_('Filter {}').format(txt))
        f.setClearButtonEnabled(True)
        l.addWidget(f)

        self.model = QStringListModel(sorted(names, key=sort_key))
        self.pmodel = QSortFilterProxyModel(self)
        self.pmodel.setFilterCaseSensitivity(
            Qt.CaseSensitivity.CaseInsensitive)
        f.textChanged.connect(self.pmodel.setFilterFixedString)
        self.pmodel.setSourceModel(self.model)
        self._names = QListView(self)
        self._names.setModel(self.pmodel)
        self._names.setSelectionMode(
            QAbstractItemView.SelectionMode.MultiSelection)
        l.addWidget(self._names)

        self._or = QRadioButton(_('Match any of the selected %s') % txt)
        self._and = QRadioButton(_('Match all of the selected %s') % txt)
        self._or.setChecked(True)
        l.addWidget(self._or)
        l.addWidget(self._and)

        self.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok
                                   | QDialogButtonBox.StandardButton.Cancel)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        l.addWidget(self.bb)

        self.resize(self.sizeHint())
示例#13
0
    def genesis(self, gui):
        self.gui = gui

        r = self.register

        r('read_file_metadata', prefs)
        r('swap_author_names', prefs)
        r('add_formats_to_existing', prefs)
        r('check_for_dupes_on_ctl', prefs)
        r('preserve_date_on_ctl', gprefs)
        r('manual_add_auto_convert', gprefs)
        choices = [
                (_('Ignore duplicate incoming formats'), 'ignore'),
                (_('Overwrite existing duplicate formats'), 'overwrite'),
                (_('Create new record for each duplicate format'), 'new record')]
        r('automerge', gprefs, choices=choices)
        r('new_book_tags', prefs, setting=CommaSeparatedList)
        r('mark_new_books', prefs)
        r('auto_add_path', gprefs, restart_required=True)
        r('auto_add_everything', gprefs, restart_required=True)
        r('auto_add_check_for_duplicates', gprefs)
        r('auto_add_auto_convert', gprefs)
        r('auto_convert_same_fmt', gprefs)

        self.filename_pattern = FilenamePattern(self)
        self.metadata_box.l = QVBoxLayout(self.metadata_box)
        self.metadata_box.layout().insertWidget(0, self.filename_pattern)
        self.filename_pattern.changed_signal.connect(self.changed_signal.emit)
        self.auto_add_browse_button.clicked.connect(self.choose_aa_path)
        for signal in ('Activated', 'Changed', 'DoubleClicked', 'Clicked'):
            signal = getattr(self.opt_blocked_auto_formats, 'item'+signal)
            signal.connect(self.blocked_auto_formats_changed)
        self.tag_map_rules = self.add_filter_rules = self.author_map_rules = None
        self.tag_map_rules_button.clicked.connect(self.change_tag_map_rules)
        self.author_map_rules_button.clicked.connect(self.change_author_map_rules)
        self.add_filter_rules_button.clicked.connect(self.change_add_filter_rules)
        self.tabWidget.setCurrentIndex(0)
        self.actions_tab.layout().setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)
示例#14
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.l = l = QVBoxLayout(self)
        self.h = h = QHBoxLayout()
        l.addLayout(h)

        english_sentence = '{action_type} {action_data}'
        sentence = _('{action_type} {action_data}')
        if set(sentence.split()) != set(english_sentence.split()):
            sentence = english_sentence
        parts = sentence.split()
        for clause in parts:
            if clause == '{action_data}':
                self.action_data = w = QLineEdit(self)
                w.setClearButtonEnabled(True)
            elif clause == '{action_type}':
                self.action_type = w = QComboBox(self)
                for action, ac in ACTION_MAP.items():
                    w.addItem(ac.short_text, action)
                w.currentIndexChanged.connect(self.update_state)
            h.addWidget(w)
            if clause is not parts[-1]:
                h.addWidget(QLabel('\xa0'))
        self.h2 = h = QHBoxLayout()
        l.addLayout(h)

        self.remove_button = b = QToolButton(self)
        b.setToolTip(_('Remove this action')), b.setIcon(QIcon(I('minus.png')))
        b.clicked.connect(self.request_remove)
        h.addWidget(b)
        self.action_desc = la = QLabel('')
        la.setWordWrap(True)
        la.setTextFormat(Qt.TextFormat.RichText)
        h.addWidget(la)
        self.sep = sep = QFrame(self)
        sep.setFrameShape(QFrame.Shape.HLine)
        l.addWidget(sep)
        self.update_state()
示例#15
0
    def genesis(self, gui):
        self.gui = gui
        self.l = l = QVBoxLayout()
        self.setLayout(l)
        self.confirms_reset = False

        self.la = la = QLabel(
            _('The list of devices that you have asked calibre to ignore. '
              'Uncheck a device to have calibre stop ignoring it.'))
        la.setWordWrap(True)
        l.addWidget(la)

        self.devices = f = QListWidget(self)
        l.addWidget(f)
        f.itemChanged.connect(self.changed_signal)
        f.itemDoubleClicked.connect(self.toggle_item)

        self.la2 = la = QLabel(
            _('The list of device plugins you have disabled. Uncheck an entry '
              'to enable the plugin. calibre cannot detect devices that are '
              'managed by disabled plugins.'))
        la.setWordWrap(True)
        l.addWidget(la)

        self.device_plugins = f = QListWidget(f)
        l.addWidget(f)
        f.itemChanged.connect(self.changed_signal)
        f.itemDoubleClicked.connect(self.toggle_item)

        self.reset_confirmations_button = b = QPushButton(
            _('Reset allowed devices'))
        b.setToolTip(
            textwrap.fill(
                _('This will erase the list of devices that calibre knows about'
                  ' causing it to ask you for permission to manage them again,'
                  ' the next time they connect')))
        b.clicked.connect(self.reset_confirmations)
        l.addWidget(b)
示例#16
0
文件: toc.py 项目: qykth-git/calibre
    def __init__(self, title=None, parent=None):
        QDialog.__init__(self, parent)
        self.last_reject_at = self.last_accept_at = -1000

        t = title or current_container().mi.title
        self.book_title = t
        self.setWindowTitle(_('Edit the ToC in %s') % t)
        self.setWindowIcon(QIcon(I('toc.png')))

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

        self.stacks = s = QStackedWidget(self)
        l.addWidget(s)
        self.toc_view = TOCView(self, tprefs)
        self.toc_view.add_new_item.connect(self.add_new_item)
        s.addWidget(self.toc_view)
        self.item_edit = ItemEdit(self, tprefs)
        s.addWidget(self.item_edit)

        bb = self.bb = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Ok
            | QDialogButtonBox.StandardButton.Cancel)
        l.addWidget(bb)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.undo_button = b = bb.addButton(
            _('&Undo'), QDialogButtonBox.ButtonRole.ActionRole)
        b.setToolTip(_('Undo the last action, if any'))
        b.setIcon(QIcon(I('edit-undo.png')))
        b.clicked.connect(self.toc_view.undo)

        self.read_toc()

        self.resize(950, 630)
        geom = tprefs.get('toc_editor_window_geom', None)
        if geom is not None:
            QApplication.instance().safe_restore_geometry(self, bytes(geom))
示例#17
0
    def link_stylesheets(self, names):
        s = self.categories['styles']
        sheets = [str(s.child(i).data(0, NAME_ROLE) or '') for i in range(s.childCount())]
        if not sheets:
            return error_dialog(self, _('No stylesheets'), _(
                'This book currently has no stylesheets. You must first create a stylesheet'
                ' before linking it.'), show=True)
        d = QDialog(self)
        d.l = l = QVBoxLayout(d)
        d.setLayout(l)
        d.setWindowTitle(_('Choose stylesheets'))
        d.la = la = QLabel(_('Choose the stylesheets to link. Drag and drop to re-arrange'))

        la.setWordWrap(True)
        l.addWidget(la)
        d.s = s = QListWidget(d)
        l.addWidget(s)
        s.setDragEnabled(True)
        s.setDropIndicatorShown(True)
        s.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
        s.setAutoScroll(True)
        s.setDefaultDropAction(Qt.DropAction.MoveAction)
        for name in sheets:
            i = QListWidgetItem(name, s)
            flags = Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsDragEnabled | Qt.ItemFlag.ItemIsSelectable
            i.setFlags(flags)
            i.setCheckState(Qt.CheckState.Checked)
        d.r = r = QCheckBox(_('Remove existing links to stylesheets'))
        r.setChecked(tprefs['remove_existing_links_when_linking_sheets'])
        l.addWidget(r)
        d.bb = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
        bb.accepted.connect(d.accept), bb.rejected.connect(d.reject)
        l.addWidget(bb)
        if d.exec() == QDialog.DialogCode.Accepted:
            tprefs['remove_existing_links_when_linking_sheets'] = r.isChecked()
            sheets = [str(s.item(il).text()) for il in range(s.count()) if s.item(il).checkState() == Qt.CheckState.Checked]
            if sheets:
                self.link_stylesheets_requested.emit(names, sheets, r.isChecked())
示例#18
0
    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)
示例#19
0
    def setup_ui(self):
        from calibre.gui2.ui import get_gui
        db = get_gui().current_db
        self.l = l = QVBoxLayout(self)
        b = self.bb.addButton(_('&Add search'), QDialogButtonBox.ButtonRole.ActionRole)
        b.setIcon(QIcon(I('plus.png')))
        b.clicked.connect(self.add_search)

        b = self.bb.addButton(_('&Remove search'), QDialogButtonBox.ButtonRole.ActionRole)
        b.setIcon(QIcon(I('minus.png')))
        b.clicked.connect(self.del_search)

        b = self.bb.addButton(_('&Edit search'), QDialogButtonBox.ButtonRole.ActionRole)
        b.setIcon(QIcon(I('modified.png')))
        b.clicked.connect(self.edit_search)

        self.slist = QListWidget(self)
        self.slist.setStyleSheet('QListView::item { padding: 3px }')
        self.slist.activated.connect(self.edit_search)
        self.slist.setAlternatingRowColors(True)
        self.searches = {name: db.saved_search_lookup(name) for name in db.saved_search_names()}
        self.populate_search_list()
        if self.initial_search is not None and self.initial_search in self.searches:
            self.select_search(self.initial_search)
        elif self.searches:
            self.slist.setCurrentRow(0)
        self.slist.currentItemChanged.connect(self.current_index_changed)
        l.addWidget(self.slist)

        self.desc = la = QLabel('\xa0')
        la.setWordWrap(True)
        l.addWidget(la)

        l.addWidget(self.bb)
        self.current_index_changed(self.slist.currentItem())
        self.setMinimumHeight(500)
        self.setMinimumWidth(600)
示例#20
0
def show_report(changed, title, report, parent, show_current_diff):
    report = format_report(title, report)
    d = QDialog(parent)
    d.setWindowTitle(_('Action report'))
    d.l = QVBoxLayout()
    d.setLayout(d.l)
    d.e = QTextBrowser(d)
    d.l.addWidget(d.e)
    d.e.setHtml(report)
    d.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
    d.show_changes = False
    if changed:
        b = d.b = d.bb.addButton(_('See what &changed'),
                                 QDialogButtonBox.ButtonRole.AcceptRole)
        b.setIcon(QIcon(I('diff.png'))), b.setAutoDefault(False)
        connect_lambda(b.clicked, d,
                       lambda d: setattr(d, 'show_changes', True))
    b = d.bb.addButton(_('&Copy to clipboard'),
                       QDialogButtonBox.ButtonRole.ActionRole)
    b.setIcon(QIcon(I('edit-copy.png'))), b.setAutoDefault(False)

    def copy_report():
        text = re.sub(r'</.+?>', '\n', report)
        text = re.sub(r'<.+?>', '', text)
        cp = QApplication.instance().clipboard()
        cp.setText(text)

    b.clicked.connect(copy_report)
    d.bb.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
    d.l.addWidget(d.bb)
    d.bb.rejected.connect(d.reject)
    d.bb.accepted.connect(d.accept)
    d.resize(600, 400)
    d.exec()
    b.clicked.disconnect()
    if d.show_changes:
        show_current_diff(allow_revert=True)
示例#21
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)
示例#22
0
 def setup_ui(self):
     self.l = l = QVBoxLayout(self)
     if self.html_view:
         self.tb = w = QTextBrowser(self)
     else:
         self.log = w = QPlainTextEdit(self)
         w.setReadOnly(True), w.setLineWrapMode(
             QPlainTextEdit.LineWrapMode.NoWrap)
     l.addWidget(w)
     l.addWidget(self.bb)
     self.bb.clear(), self.bb.setStandardButtons(
         QDialogButtonBox.StandardButton.Close)
     self.copy_button = b = self.bb.addButton(
         _('&Copy to clipboard'), QDialogButtonBox.ButtonRole.ActionRole)
     b.setIcon(QIcon(I('edit-copy.png')))
     b.clicked.connect(self.copy_to_clipboard)
     self.next_pos = 0
     self.update()
     self.timer = QTimer(self)
     self.timer.timeout.connect(self.update)
     self.timer.start(1000)
     if not self.html_view:
         v = self.log.verticalScrollBar()
         v.setValue(v.maximum())
示例#23
0
    def __init__(self, devs, blacklist):
        QWidget.__init__(self)
        self.l = l = QVBoxLayout()
        self.setLayout(l)
        self.la = la = QLabel('<p>' + _(
            '''Select the devices to be <b>ignored</b>. calibre <b>will not</b>
            connect to devices with a checkmark next to their names.'''))
        la.setWordWrap(True)
        l.addWidget(la)
        self.f = f = QListWidget(self)
        l.addWidget(f)

        devs = [(snum, (x[0], parse_date(x[1])))
                for snum, x in iteritems(devs)]
        for dev, x in sorted(devs, key=lambda x: x[1][1], reverse=True):
            name = x[0]
            name = '%s [%s]' % (name, dev)
            item = QListWidgetItem(name, f)
            item.setData(Qt.ItemDataRole.UserRole, dev)
            item.setFlags(Qt.ItemFlag.ItemIsEnabled
                          | Qt.ItemFlag.ItemIsUserCheckable
                          | Qt.ItemFlag.ItemIsSelectable)
            item.setCheckState(Qt.CheckState.Checked if dev in
                               blacklist else Qt.CheckState.Unchecked)
示例#24
0
 def setup_ui(self):
     self.l = l = QVBoxLayout(self)
     self.edit_widget = w = self.RulesClass(self)
     l.addWidget(w)
     ebw = self.extra_bottom_widget()
     if ebw is None:
         l.addWidget(self.bb)
     else:
         self.h = h = QHBoxLayout()
         l.addLayout(h)
         h.addWidget(ebw), h.addStretch(10), h.addWidget(self.bb)
     self.save_button = b = self.bb.addButton(
         _('&Save'), QDialogButtonBox.ButtonRole.ActionRole)
     b.setToolTip(_('Save this ruleset for later re-use'))
     b.clicked.connect(self.save_ruleset)
     self.load_button = b = self.bb.addButton(
         _('&Load'), QDialogButtonBox.ButtonRole.ActionRole)
     b.setToolTip(_('Load a previously saved ruleset'))
     self.load_menu = QMenu(self)
     b.setMenu(self.load_menu)
     self.build_load_menu()
     self.test_button = b = self.bb.addButton(
         _('&Test rules'), QDialogButtonBox.ButtonRole.ActionRole)
     b.clicked.connect(self.test_rules)
示例#25
0
    def setup_ui(self):
        self.l = l = QVBoxLayout(self)
        self.stack = s = QStackedWidget(self)
        l.addWidget(s)

        self.recipe_list = rl = RecipeList(self, self.recipe_model)
        rl.edit_recipe.connect(self.edit_recipe)
        s.addWidget(rl)

        self.basic_recipe = br = BasicRecipe(self)
        s.addWidget(br)

        self.advanced_recipe = ar = AdvancedRecipe(self)
        s.addWidget(ar)

        l.addWidget(self.bb)
        self.list_actions = []
        la = lambda *args: self.list_actions.append(args)
        la('plus.png', _('&New recipe'), _('Create a new recipe from scratch'),
           self.add_recipe)
        la('news.png', _('Customize &builtin recipe'),
           _('Customize a builtin news download source'),
           self.customize_recipe)
        la('document_open.png', _('Load recipe from &file'),
           _('Load a recipe from a file'), self.load_recipe)
        la('mimetypes/dir.png', _('&Show recipe files'),
           _('Show the folder containing all recipe files'),
           self.show_recipe_files)
        la(
            'mimetypes/opml.png', _('Import &OPML'),
            _("Import a collection of RSS feeds in OPML format\n"
              "Many RSS readers can export their subscribed RSS feeds\n"
              "in OPML format"), self.import_opml)

        s.currentChanged.connect(self.update_button_box)
        self.update_button_box()
示例#26
0
class PluginTweaks(QDialog):  # {{{

    def __init__(self, raw, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle(_('Plugin tweaks'))
        self.edit = QPlainTextEdit(self)
        self.highlighter = PythonHighlighter(self.edit.document())
        self.l = QVBoxLayout()
        self.setLayout(self.l)
        self.msg = QLabel(
            _('Add/edit tweaks for any custom plugins you have installed. '
                'Documentation for these tweaks should be available '
                'on the website from where you downloaded the plugins.'))
        self.msg.setWordWrap(True)
        self.l.addWidget(self.msg)
        self.l.addWidget(self.edit)
        self.edit.setPlainText(raw)
        self.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok|QDialogButtonBox.StandardButton.Cancel,
                Qt.Orientation.Horizontal, self)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        self.l.addWidget(self.bb)
        self.resize(550, 300)
示例#27
0
def show_config_widget(category, name, gui=None, show_restart_msg=False,
        parent=None, never_shutdown=False):
    '''
    Show the preferences plugin identified by category and name

    :param gui: gui instance, if None a hidden gui is created
    :param show_restart_msg: If True and the preferences plugin indicates a
    restart is required, show a message box telling the user to restart
    :param parent: The parent of the displayed dialog

    :return: True iff a restart is required for the changes made by the user to
    take effect
    '''
    from calibre.gui2 import gprefs
    pl = get_plugin(category, name)
    d = ConfigDialog(parent)
    d.resize(750, 550)
    conf_name = 'config_widget_dialog_geometry_%s_%s'%(category, name)
    geom = gprefs.get(conf_name, None)
    d.setWindowTitle(_('Configure ') + pl.gui_name)
    d.setWindowIcon(QIcon(I('config.png')))
    bb = QDialogButtonBox(d)
    bb.setStandardButtons(QDialogButtonBox.StandardButton.Apply|QDialogButtonBox.StandardButton.Cancel|QDialogButtonBox.StandardButton.RestoreDefaults)
    bb.accepted.connect(d.accept)
    bb.rejected.connect(d.reject)
    w = pl.create_widget(d)
    d.set_widget(w)
    bb.button(QDialogButtonBox.StandardButton.RestoreDefaults).clicked.connect(w.restore_defaults)
    bb.button(QDialogButtonBox.StandardButton.RestoreDefaults).setEnabled(w.supports_restoring_to_defaults)
    bb.button(QDialogButtonBox.StandardButton.Apply).setEnabled(False)
    bb.button(QDialogButtonBox.StandardButton.Apply).clicked.connect(d.accept)

    def onchange():
        b = bb.button(QDialogButtonBox.StandardButton.Apply)
        b.setEnabled(True)
        b.setDefault(True)
        b.setAutoDefault(True)
    w.changed_signal.connect(onchange)
    bb.button(QDialogButtonBox.StandardButton.Cancel).setFocus(True)
    l = QVBoxLayout()
    d.setLayout(l)
    l.addWidget(w)
    l.addWidget(bb)
    mygui = gui is None
    if gui is None:
        gui = init_gui()
        mygui = True
    w.genesis(gui)
    w.initialize()
    if geom is not None:
        QApplication.instance().safe_restore_geometry(d, geom)
    d.exec_()
    geom = bytearray(d.saveGeometry())
    gprefs[conf_name] = geom
    rr = getattr(d, 'restart_required', False)
    if show_restart_msg and rr:
        from calibre.gui2 import warning_dialog
        warning_dialog(gui, 'Restart required', 'Restart required', show=True)
    if mygui and not never_shutdown:
        gui.shutdown()
    return rr
示例#28
0
文件: ui.py 项目: smdx023/calibre
    def __init__(self, parent):
        QFrame.__init__(self, parent)
        self.setFrameStyle(QFrame.Shape.NoFrame if gprefs['tag_browser_old_look'] else QFrame.Shape.StyledPanel)
        self._parent = parent
        self._layout = QVBoxLayout(self)
        self._layout.setContentsMargins(0,0,0,0)

        # Set up the find box & button
        self.tb_bar = tbb = TagBrowserBar(self)
        tbb.clear_find.connect(self.reset_find)
        self.alter_tb, self.item_search, self.search_button = tbb.alter_tb, tbb.item_search, tbb.search_button
        self.toggle_search_button = tbb.toggle_search_button
        self._layout.addWidget(tbb)

        self.current_find_position = None
        self.search_button.clicked.connect(self.find)
        self.item_search.lineEdit().textEdited.connect(self.find_text_changed)
        self.item_search.activated[str].connect(self.do_find)

        # The tags view
        parent.tags_view = TagsView(parent)
        self.tags_view = parent.tags_view
        self._layout.insertWidget(0, parent.tags_view)

        # Now the floating 'not found' box
        l = QLabel(self.tags_view)
        self.not_found_label = l
        l.setFrameStyle(QFrame.Shape.StyledPanel)
        l.setAutoFillBackground(True)
        l.setText('<p><b>'+_('No more matches.</b><p> Click Find again to go to first match'))
        l.setAlignment(Qt.AlignmentFlag.AlignVCenter)
        l.setWordWrap(True)
        l.resize(l.sizeHint())
        l.move(10,20)
        l.setVisible(False)
        self.not_found_label_timer = QTimer()
        self.not_found_label_timer.setSingleShot(True)
        self.not_found_label_timer.timeout.connect(self.not_found_label_timer_event,
                                                   type=Qt.ConnectionType.QueuedConnection)
        self.collapse_all_action = ac = QAction(parent)
        parent.addAction(ac)
        parent.keyboard.register_shortcut('tag browser collapse all',
                _('Collapse all'), default_keys=(),
                action=ac, group=_('Tag browser'))
        connect_lambda(ac.triggered, self, lambda self: self.tags_view.collapseAll())

        # The Configure Tag Browser button
        l = self.alter_tb
        ac = QAction(parent)
        parent.addAction(ac)
        parent.keyboard.register_shortcut('tag browser alter',
                _('Configure Tag browser'), default_keys=(),
                action=ac, group=_('Tag browser'))
        ac.triggered.connect(l.showMenu)

        l.m.aboutToShow.connect(self.about_to_show_configure_menu)
        l.m.show_counts_action = ac = l.m.addAction('counts')
        ac.triggered.connect(self.toggle_counts)
        l.m.show_avg_rating_action = ac = l.m.addAction('avg rating')
        ac.triggered.connect(self.toggle_avg_rating)
        sb = l.m.addAction(_('Sort by'))
        sb.m = l.sort_menu = QMenu(l.m)
        sb.setMenu(sb.m)
        sb.bg = QActionGroup(sb)

        # Must be in the same order as db2.CATEGORY_SORTS
        for i, x in enumerate((_('Name'), _('Number of books'),
                  _('Average rating'))):
            a = sb.m.addAction(x)
            sb.bg.addAction(a)
            a.setCheckable(True)
            if i == 0:
                a.setChecked(True)
        sb.setToolTip(
                _('Set the sort order for entries in the Tag browser'))
        sb.setStatusTip(sb.toolTip())

        ma = l.m.addAction(_('Search type when selecting multiple items'))
        ma.m = l.match_menu = QMenu(l.m)
        ma.setMenu(ma.m)
        ma.ag = QActionGroup(ma)

        # Must be in the same order as db2.MATCH_TYPE
        for i, x in enumerate((_('Match any of the items'), _('Match all of the items'))):
            a = ma.m.addAction(x)
            ma.ag.addAction(a)
            a.setCheckable(True)
            if i == 0:
                a.setChecked(True)
        ma.setToolTip(
                _('When selecting multiple entries in the Tag browser '
                    'match any or all of them'))
        ma.setStatusTip(ma.toolTip())

        mt = l.m.addAction(_('Manage authors, tags, etc.'))
        mt.setToolTip(_('All of these category_managers are available by right-clicking '
                       'on items in the Tag browser above'))
        mt.m = l.manage_menu = QMenu(l.m)
        mt.setMenu(mt.m)

        ac = QAction(parent)
        parent.addAction(ac)
        parent.keyboard.register_shortcut('tag browser toggle item',
                _("'Click' found item"), default_keys=(),
                action=ac, group=_('Tag browser'))
        ac.triggered.connect(self.toggle_item)

        ac = QAction(parent)
        parent.addAction(ac)
        parent.keyboard.register_shortcut('tag browser set focus',
                _("Give the Tag browser keyboard focus"), default_keys=(),
                action=ac, group=_('Tag browser'))
        ac.triggered.connect(self.give_tb_focus)
示例#29
0
 def __init__(self, parent=None):
     QWidget.__init__(self, parent)
     self.setVisible(False)
     self.l = QVBoxLayout(self)
     self.items = {}
示例#30
0
    def __init__(self, gui, initial_plugin=None, close_after_initial=False):
        QDialog.__init__(self, gui)
        self.gui = gui
        self.must_restart = False
        self.do_restart = False
        self.committed = False
        self.close_after_initial = close_after_initial

        self.resize(930, 720)
        nh, nw = min_available_height() - 25, available_width() - 10
        if nh < 0:
            nh = 800
        if nw < 0:
            nw = 600
        nh = min(self.height(), nh)
        nw = min(self.width(), nw)
        self.resize(nw, nh)

        geom = gprefs.get('preferences dialog geometry', None)
        if geom is not None:
            QApplication.instance().safe_restore_geometry(self, geom)

        # Center
        if islinux:
            self.move(gui.rect().center() - self.rect().center())

        self.setWindowModality(Qt.WindowModality.ApplicationModal)
        self.setWindowTitle(__appname__ + ' — ' + _('Preferences'))
        self.setWindowIcon(QIcon(I('config.png')))
        self.l = l = QVBoxLayout(self)

        self.stack = QStackedWidget(self)
        self.bb = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Close
            | QDialogButtonBox.StandardButton.Apply
            | QDialogButtonBox.StandardButton.Cancel
            | QDialogButtonBox.StandardButton.RestoreDefaults)
        self.bb.button(QDialogButtonBox.StandardButton.Apply).clicked.connect(
            self.accept)
        self.bb.button(
            QDialogButtonBox.StandardButton.RestoreDefaults).setIcon(
                QIcon(I('clear_left.png')))
        self.bb.button(
            QDialogButtonBox.StandardButton.RestoreDefaults).clicked.connect(
                self.restore_defaults)
        self.wizard_button = self.bb.addButton(
            _('Run Welcome &wizard'), QDialogButtonBox.ButtonRole.ActionRole)
        self.wizard_button.setIcon(QIcon(I('wizard.png')))
        self.wizard_button.clicked.connect(
            self.run_wizard, type=Qt.ConnectionType.QueuedConnection)
        self.wizard_button.setAutoDefault(False)
        self.bb.rejected.connect(self.reject)
        self.browser = Browser(self)
        self.browser.show_plugin.connect(self.show_plugin)
        self.stack.addWidget(self.browser)
        self.scroll_area = QScrollArea(self)
        self.stack.addWidget(self.scroll_area)
        self.scroll_area.setWidgetResizable(True)

        self.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu)
        self.title_bar = TitleBar(self)
        for ac, tt in [(QDialogButtonBox.StandardButton.Apply,
                        _('Save changes')),
                       (QDialogButtonBox.StandardButton.Cancel,
                        _('Cancel and return to overview'))]:
            self.bb.button(ac).setToolTip(tt)

        l.addWidget(self.title_bar), l.addWidget(self.stack), l.addWidget(
            self.bb)

        if initial_plugin is not None:
            category, name = initial_plugin[:2]
            plugin = get_plugin(category, name)
            if plugin is not None:
                self.show_plugin(plugin)
                if len(initial_plugin) > 2:
                    w = self.findChild(QWidget, initial_plugin[2])
                    if w is not None:
                        for c in self.showing_widget.children():
                            if isinstance(c, QTabWidget):
                                idx = c.indexOf(w)
                                if idx > -1:
                                    c.setCurrentIndex(idx)
                                    break
        else:
            self.hide_plugin()