예제 #1
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)
예제 #2
0
def test():
    app = QApplication([])
    app
    d = QDialog()
    d.setLayout(QVBoxLayout())
    d.layout().addWidget(FontFamilyChooser(d))
    d.layout().addWidget(QFontComboBox(d))
    d.exec_()
예제 #3
0
def customize_remove_unused_css(name, parent, ans):
    d = QDialog(parent)
    d.l = l = QVBoxLayout()
    d.setLayout(d.l)
    d.setWindowTitle(_('Remove unused CSS'))

    def label(text):
        la = QLabel(text)
        la.setWordWrap(True), l.addWidget(la), la.setMinimumWidth(450)
        l.addWidget(la)
        return la

    d.la = label(
        _('This will remove all CSS rules that do not match any actual content.'
          ' There are a couple of additional cleanups you can enable, below:'))
    d.c = c = QCheckBox(_('Remove unused &class attributes'))
    c.setChecked(tprefs['remove_unused_classes'])
    l.addWidget(c)
    d.la2 = label('<span style="font-size:small; font-style: italic">' + _(
        'Remove all class attributes from the HTML that do not match any existing CSS rules'
    ))
    d.m = m = QCheckBox(_('Merge CSS rules with identical &selectors'))
    m.setChecked(tprefs['merge_identical_selectors'])
    l.addWidget(m)
    d.la3 = label('<span style="font-size:small; font-style: italic">' + _(
        'Merge CSS rules in the same stylesheet that have identical selectors.'
        ' Note that in rare cases merging can result in a change to the effective styling'
        ' of the book, so use with care.'))
    d.p = p = QCheckBox(_('Merge CSS rules with identical &properties'))
    p.setChecked(tprefs['merge_rules_with_identical_properties'])
    l.addWidget(p)
    d.la4 = label('<span style="font-size:small; font-style: italic">' + _(
        'Merge CSS rules in the same stylesheet that have identical properties.'
        ' Note that in rare cases merging can result in a change to the effective styling'
        ' of the book, so use with care.'))
    d.u = u = QCheckBox(_('Remove &unreferenced style sheets'))
    u.setChecked(tprefs['remove_unreferenced_sheets'])
    l.addWidget(u)
    d.la5 = label(
        '<span style="font-size:small; font-style: italic">' +
        _('Remove stylesheets that are not referenced by any content.'))

    d.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok
                            | QDialogButtonBox.StandardButton.Cancel)
    d.l.addWidget(d.bb)
    d.bb.rejected.connect(d.reject)
    d.bb.accepted.connect(d.accept)
    ret = d.exec()
    ans['remove_unused_classes'] = tprefs[
        'remove_unused_classes'] = c.isChecked()
    ans['merge_identical_selectors'] = tprefs[
        'merge_identical_selectors'] = m.isChecked()
    ans['merge_rules_with_identical_properties'] = tprefs[
        'merge_rules_with_identical_properties'] = p.isChecked()
    ans['remove_unreferenced_sheets'] = tprefs[
        'remove_unreferenced_sheets'] = u.isChecked()
    if ret != QDialog.DialogCode.Accepted:
        raise Abort()
예제 #4
0
def test():
    from calibre.gui2 import Application
    app = Application([])
    app
    d = QDialog()
    d.setLayout(QVBoxLayout())
    d.layout().addWidget(FontFamilyChooser(d))
    d.layout().addWidget(QFontComboBox(d))
    d.exec()
예제 #5
0
    def view_server_logs(self):
        from calibre.srv.embedded import log_paths
        log_error_file, log_access_file = log_paths()
        d = QDialog(self)
        d.resize(QSize(800, 600))
        layout = QVBoxLayout()
        d.setLayout(layout)
        layout.addWidget(QLabel(_('Error log:')))
        el = QPlainTextEdit(d)
        layout.addWidget(el)
        try:
            el.setPlainText(
                share_open(log_error_file, 'rb').read().decode('utf8', 'replace')
            )
        except EnvironmentError:
            el.setPlainText(_('No error log found'))
        layout.addWidget(QLabel(_('Access log:')))
        al = QPlainTextEdit(d)
        layout.addWidget(al)
        try:
            al.setPlainText(
                share_open(log_access_file, 'rb').read().decode('utf8', 'replace')
            )
        except EnvironmentError:
            al.setPlainText(_('No access log found'))
        loc = QLabel(_('The server log files are in: {}').format(os.path.dirname(log_error_file)))
        loc.setWordWrap(True)
        layout.addWidget(loc)
        bx = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok)
        layout.addWidget(bx)
        bx.accepted.connect(d.accept)
        b = bx.addButton(_('&Clear logs'), QDialogButtonBox.ButtonRole.ActionRole)

        def clear_logs():
            if getattr(self.server, 'is_running', False):
                return error_dialog(d, _('Server running'), _(
                    'Cannot clear logs while the server is running. First stop the server.'), show=True)
            if self.server:
                self.server.access_log.clear()
                self.server.log.clear()
            else:
                for x in (log_error_file, log_access_file):
                    try:
                        os.remove(x)
                    except EnvironmentError as err:
                        if err.errno != errno.ENOENT:
                            raise
            el.setPlainText(''), al.setPlainText('')

        b.clicked.connect(clear_logs)
        d.show()
예제 #6
0
def get_bulk_rename_settings(parent, number, msg=None, sanitize=sanitize_file_name,
        leading_zeros=True, prefix=None, category='text', allow_spine_order=False):  # {{{
    d = QDialog(parent)
    d.setWindowTitle(_('Bulk rename items'))
    d.l = l = QFormLayout(d)
    d.setLayout(l)
    d.prefix = p = QLineEdit(d)
    default_prefix = {k:v for k, __, v in CATEGORIES}.get(category, _('Chapter-'))
    previous = tprefs.get('file-list-bulk-rename-prefix', {})
    prefix = prefix or previous.get(category, default_prefix)
    p.setText(prefix)
    p.selectAll()
    d.la = la = QLabel(msg or _(
        'All selected files will be renamed to the form prefix-number'))
    l.addRow(la)
    l.addRow(_('&Prefix:'), p)
    d.num = num = QSpinBox(d)
    num.setMinimum(0), num.setValue(1), num.setMaximum(1000)
    l.addRow(_('Starting &number:'), num)
    if allow_spine_order:
        d.spine_order = QCheckBox(_('Rename files according to their book order'))
        d.spine_order.setToolTip(textwrap.fill(_(
            'Rename the selected files according to the order they appear in the book, instead of the order they were selected in.')))
        l.addRow(d.spine_order)
    d.bb = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
    bb.accepted.connect(d.accept), bb.rejected.connect(d.reject)
    l.addRow(bb)
    ans = {'prefix': None, 'start': None}

    if d.exec() == QDialog.DialogCode.Accepted:
        prefix = sanitize(str(d.prefix.text()))
        previous[category] = prefix
        tprefs.set('file-list-bulk-rename-prefix', previous)
        num = d.num.value()
        fmt = '%d'
        if leading_zeros:
            largest = num + number - 1
            fmt = f'%0{len(str(largest))}d'
        ans['prefix'] = prefix + fmt
        ans['start'] = num
        if allow_spine_order:
            ans['spine_order'] = d.spine_order.isChecked()
    return ans
예제 #7
0
 def show_debug_info(self):
     info = self.device.device_debug_info()
     d = QDialog(self)
     d.l = l = QVBoxLayout()
     d.setLayout(l)
     d.v = v = QPlainTextEdit()
     d.setWindowTitle(self.device.get_gui_name())
     v.setPlainText(info)
     v.setMinimumWidth(400)
     v.setMinimumHeight(350)
     l.addWidget(v)
     bb = d.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
     bb.accepted.connect(d.accept)
     bb.rejected.connect(d.reject)
     l.addWidget(bb)
     bb.addButton(_('Copy to clipboard'), QDialogButtonBox.ButtonRole.ActionRole)
     bb.clicked.connect(lambda :
             QApplication.clipboard().setText(v.toPlainText()))
     d.exec_()
예제 #8
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())
예제 #9
0
                    '<br>'+str(err), show=True)

            return False
# }}}


if __name__ == '__main__':
    from calibre.gui2 import Application
    from calibre.devices.kobo.driver import KOBOTOUCH
    from calibre.devices.scanner import DeviceScanner
    s = DeviceScanner()
    s.scan()
    app = Application([])
    debug_print("KOBOTOUCH:", KOBOTOUCH)
    dev = KOBOTOUCH(None)
#     dev.startup()
#     cd = dev.detect_managed_devices(s.devices)
#     dev.open(cd, 'test')
    cw = dev.config_widget()
    d = QDialog()
    d.l = QVBoxLayout()
    d.setLayout(d.l)
    d.l.addWidget(cw)
    bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok|QDialogButtonBox.StandardButton.Cancel)
    d.l.addWidget(bb)
    bb.accepted.connect(d.accept)
    bb.rejected.connect(d.reject)
    if d.exec() == QDialog.DialogCode.Accepted:
        cw.commit()
    dev.shutdown()
예제 #10
0
        EnComboBox.clear(self)

    def eventFilter(self, obj, e):
        try:
            c = self.lineEdit().mcompleter
        except AttributeError:
            return False
        etype = e.type()
        if self.eat_focus_out and self is obj and etype == QEvent.Type.FocusOut:
            if c.isVisible():
                return True
        return EnComboBox.eventFilter(self, obj, e)


if __name__ == '__main__':
    from qt.core import QDialog, QVBoxLayout
    from calibre.gui2 import Application
    app = Application([])
    d = QDialog()
    d.setLayout(QVBoxLayout())
    le = EditWithComplete(d)
    d.layout().addWidget(le)
    items = [
        'oane\n line2\n line3', 'otwo', 'othree', 'ooone', 'ootwo', 'other',
        'odd', 'over', 'orc', 'oven', 'owe', 'oothree', 'a1', 'a2', 'Edgas',
        'Èdgar', 'Édgaq', 'Edgar', 'Édgar'
    ]
    le.update_items_cache(items)
    le.show_initial_value('')
    d.exec()
예제 #11
0
def ask_about_cc_mismatch(gui, db, newdb, missing_cols,
                          incompatible_cols):  # {{{
    source_metadata = db.field_metadata.custom_field_metadata(
        include_composites=True)
    dest_library_path = newdb.library_path
    ndbname = os.path.basename(dest_library_path)

    d = QDialog(gui)
    d.setWindowTitle(_('Different custom columns'))
    l = QFormLayout()
    tl = QVBoxLayout()
    d.setLayout(tl)
    d.s = QScrollArea(d)
    tl.addWidget(d.s)
    d.w = QWidget(d)
    d.s.setWidget(d.w)
    d.s.setWidgetResizable(True)
    d.w.setLayout(l)
    d.setMinimumWidth(600)
    d.setMinimumHeight(500)
    d.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok
                            | QDialogButtonBox.StandardButton.Cancel)

    msg = _(
        'The custom columns in the <i>{0}</i> library are different from the '
        'custom columns in the <i>{1}</i> library. As a result, some metadata might not be copied.'
    ).format(os.path.basename(db.library_path), ndbname)
    d.la = la = QLabel(msg)
    la.setWordWrap(True)
    la.setStyleSheet('QLabel { margin-bottom: 1.5ex }')
    l.addRow(la)
    if incompatible_cols:
        la = d.la2 = QLabel(
            _('The following columns are incompatible - they have the same name'
              ' but different data types. They will be ignored: ') +
            ', '.join(sorted(incompatible_cols, key=sort_key)))
        la.setWordWrap(True)
        la.setStyleSheet('QLabel { margin-bottom: 1.5ex }')
        l.addRow(la)

    missing_widgets = []
    if missing_cols:
        la = d.la3 = QLabel(
            _('The following columns are missing in the <i>{0}</i> library.'
              ' You can choose to add them automatically below.').format(
                  ndbname))
        la.setWordWrap(True)
        l.addRow(la)
        for k in missing_cols:
            widgets = (k, QCheckBox(_('Add to the %s library') % ndbname))
            l.addRow(QLabel(k), widgets[1])
            missing_widgets.append(widgets)
    d.la4 = la = QLabel(
        _('This warning is only shown once per library, per session'))
    la.setWordWrap(True)
    tl.addWidget(la)

    tl.addWidget(d.bb)
    d.bb.accepted.connect(d.accept)
    d.bb.rejected.connect(d.reject)
    d.resize(d.sizeHint())
    if d.exec_() == QDialog.DialogCode.Accepted:
        changes_made = False
        for k, cb in missing_widgets:
            if cb.isChecked():
                col_meta = source_metadata[k]
                newdb.create_custom_column(col_meta['label'], col_meta['name'],
                                           col_meta['datatype'],
                                           len(col_meta['is_multiple']) > 0,
                                           col_meta['is_editable'],
                                           col_meta['display'])
                changes_made = True
        if changes_made:
            # Unload the db so that the changes are available
            # when it is next accessed
            from calibre.gui2.ui import get_gui
            library_broker = get_gui().library_broker
            library_broker.unload_library(dest_library_path)
        return True
    return False