Exemplo n.º 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.Close)
    if changed:
        b = d.b = d.bb.addButton(_('See what &changed'), d.bb.AcceptRole)
        b.setIcon(QIcon(I('diff.png'))), b.setAutoDefault(False)
        b.clicked.connect(lambda : show_current_diff(allow_revert=True), type=Qt.QueuedConnection)
    b = d.bb.addButton(_('&Copy to clipboard'), d.bb.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(d.bb.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()
Exemplo n.º 2
0
    def view_server_logs(self):
        from calibre.library.server import log_access_file, log_error_file

        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(open(log_error_file, "rb").read().decode("utf8", "replace"))
        except IOError:
            el.setPlainText("No error log found")
        layout.addWidget(QLabel(_("Access log:")))
        al = QPlainTextEdit(d)
        layout.addWidget(al)
        try:
            al.setPlainText(open(log_access_file, "rb").read().decode("utf8", "replace"))
        except IOError:
            al.setPlainText("No access log found")
        bx = QDialogButtonBox(QDialogButtonBox.Ok)
        layout.addWidget(bx)
        bx.accepted.connect(d.accept)
        d.show()
Exemplo n.º 3
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(
             lopen(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(
             lopen(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.Ok)
     layout.addWidget(bx)
     bx.accepted.connect(d.accept)
     d.show()
Exemplo n.º 4
0
    def add_builtin_recipe(self):
        from calibre.web.feeds.recipes.collection import \
            get_builtin_recipe_collection, get_builtin_recipe_by_id
        from PyQt5.Qt import QDialog, QVBoxLayout, QListWidgetItem, \
                QListWidget, QDialogButtonBox, QSize

        d = QDialog(self)
        d.l = QVBoxLayout()
        d.setLayout(d.l)
        d.list = QListWidget(d)
        d.list.doubleClicked.connect(lambda x: d.accept())
        d.l.addWidget(d.list)
        d.bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel,
                Qt.Horizontal, d)
        d.bb.accepted.connect(d.accept)
        d.bb.rejected.connect(d.reject)
        d.l.addWidget(d.bb)
        d.setWindowTitle(_('Choose builtin recipe'))
        items = []
        for r in get_builtin_recipe_collection():
            id_ = r.get('id', '')
            title = r.get('title', '')
            lang = r.get('language', '')
            if id_ and title:
                items.append((title + ' [%s]'%lang, id_))

        items.sort(key=lambda x:sort_key(x[0]))
        for title, id_ in items:
            item = QListWidgetItem(title)
            item.setData(Qt.UserRole, id_)
            d.list.addItem(item)

        d.resize(QSize(450, 400))
        ret = d.exec_()
        d.list.doubleClicked.disconnect()
        if ret != d.Accepted:
            return

        items = list(d.list.selectedItems())
        if not items:
            return
        item = items[-1]
        id_ = unicode(item.data(Qt.UserRole) or '')
        title = unicode(item.data(Qt.DisplayRole) or '').rpartition(' [')[0]
        profile = get_builtin_recipe_by_id(id_, download_recipe=True)
        if profile is None:
            raise Exception('Something weird happened')

        if self._model.has_title(title):
            if question_dialog(self, _('Replace recipe?'),
                _('A custom recipe named %s already exists. Do you want to '
                    'replace it?')%title):
                self._model.replace_by_title(title, profile)
            else:
                return
        else:
            self.model.add(title, profile)

        self.clear()
Exemplo n.º 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(
                lopen(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(
                lopen(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.Ok)
        layout.addWidget(bx)
        bx.accepted.connect(d.accept)
        b = bx.addButton(_('&Clear logs'), bx.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()
Exemplo n.º 6
0
    def ask_link(self):
        d = QDialog(self)
        d.setWindowTitle(_('Create link'))
        l = QFormLayout()
        l.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        d.setLayout(l)
        d.url = QLineEdit(d)
        d.name = QLineEdit(d)
        d.treat_as_image = QCheckBox(d)
        d.setMinimumWidth(600)
        d.bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        d.br = b = QPushButton(_('&Browse'))
        b.setIcon(QIcon(I('document_open.png')))

        def cf():
            files = choose_files(d, 'select link file', _('Choose file'), select_only_single_file=True)
            if files:
                path = files[0]
                d.url.setText(path)
                if path and os.path.exists(path):
                    with lopen(path, 'rb') as f:
                        q = what(f)
                    is_image = q in {'jpeg', 'png', 'gif'}
                    d.treat_as_image.setChecked(is_image)

        b.clicked.connect(cf)
        d.la = la = QLabel(_(
            'Enter a URL. If you check the "Treat the URL as an image" box '
            'then the URL will be added as an image reference instead of as '
            'a link. You can also choose to create a link to a file on '
            'your computer. '
            'Note that if you create a link to a file on your computer, it '
            'will stop working if the file is moved.'))
        la.setWordWrap(True)
        la.setStyleSheet('QLabel { margin-bottom: 1.5ex }')
        l.setWidget(0, l.SpanningRole, la)
        l.addRow(_('Enter &URL:'), d.url)
        l.addRow(_('Treat the URL as an &image'), d.treat_as_image)
        l.addRow(_('Enter &name (optional):'), d.name)
        l.addRow(_('Choose a file on your computer:'), d.br)
        l.addRow(d.bb)
        d.bb.accepted.connect(d.accept)
        d.bb.rejected.connect(d.reject)
        d.resize(d.sizeHint())
        link, name, is_image = None, None, False
        if d.exec_() == d.Accepted:
            link, name = unicode(d.url.text()).strip(), unicode(d.name.text()).strip()
            is_image = d.treat_as_image.isChecked()
        return link, name, is_image
Exemplo n.º 7
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.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:
            d.restoreGeometry(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()
Exemplo n.º 8
0
    def customize_recipe(self):
        d = QDialog(self)
        d.l = QVBoxLayout()
        d.setLayout(d.l)
        d.list = QListWidget(d)
        d.list.doubleClicked.connect(lambda x: d.accept())
        d.l.addWidget(d.list)
        d.bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel,
                Qt.Horizontal, d)
        d.bb.accepted.connect(d.accept)
        d.bb.rejected.connect(d.reject)
        d.l.addWidget(d.bb)
        d.setWindowTitle(_('Choose builtin recipe'))
        items = []
        for r in get_builtin_recipe_collection():
            id_ = r.get('id', '')
            title = r.get('title', '')
            lang = r.get('language', '')
            if id_ and title:
                items.append((title + ' [%s]'%lang, id_))

        items.sort(key=lambda x:sort_key(x[0]))
        for title, id_ in items:
            item = QListWidgetItem(title)
            item.setData(Qt.UserRole, id_)
            d.list.addItem(item)

        d.resize(QSize(450, 400))
        ret = d.exec_()
        d.list.doubleClicked.disconnect()
        if ret != d.Accepted:
            return

        items = list(d.list.selectedItems())
        if not items:
            return
        item = items[-1]
        id_ = unicode(item.data(Qt.UserRole) or '')
        title = unicode(item.data(Qt.DisplayRole) or '').rpartition(' [')[0]
        src = get_builtin_recipe_by_id(id_, download_recipe=True)
        if src is None:
            raise Exception('Something weird happened')

        self.edit_recipe(None, src)
Exemplo n.º 9
0
def show_report(changed, title, report, parent, show_current_diff):
    report = format_report(title, report)
    d = QDialog(parent)
    d.l = QVBoxLayout()
    d.setLayout(d.l)
    d.e = QTextBrowser(d)
    d.l.addWidget(d.e)
    d.e.setHtml(report)
    d.bb = QDialogButtonBox(QDialogButtonBox.Close)
    if changed:
        b = d.b = d.bb.addButton(_('See what &changed'), d.bb.AcceptRole)
        b.setIcon(QIcon(I('diff.png'))), b.setAutoDefault(False)
        b.clicked.connect(partial(show_current_diff, allow_revert=True))
    d.bb.button(d.bb.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_()
Exemplo n.º 10
0
    def start(self):
        self.setCurrentWidget(self.wp)
        self.wp.start()

    def stop(self):
        self.wp.stop()
        self.setCurrentWidget(self.after)

    @property
    def msg(self):
        return self.wp.msg

    @msg.setter
    def msg(self, val):
        self.wp.msg = val


if __name__ == '__main__':
    from calibre.gui2 import Application
    app = Application([])
    d = QDialog()
    d.resize(64, 64)
    w = ProgressSpinner(d)
    l = QVBoxLayout(d)
    l.addWidget(w)
    w.start()
    d.exec_()
    del d
    del app
Exemplo n.º 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)
    ndbname = os.path.basename(newdb.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.Ok|QDialogButtonBox.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_() == d.Accepted:
        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'])
        return True
    return False
Exemplo n.º 12
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.Ok | QDialogButtonBox.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_() == d.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
Exemplo n.º 13
0
    def start(self):
        self.setCurrentWidget(self.wp)
        self.wp.start()

    def stop(self):
        self.wp.stop()
        self.setCurrentWidget(self.after)

    @property
    def msg(self):
        return self.wp.msg

    @msg.setter
    def msg(self, val):
        self.wp.msg = val


if __name__ == '__main__':
    from calibre.gui2 import Application
    app = Application([])
    d = QDialog()
    d.resize(64, 64)
    w = ProgressSpinner(d)
    l = QVBoxLayout(d)
    l.addWidget(w)
    w.start()
    d.exec_()
    del d
    del app
Exemplo n.º 14
0
    def __init__(self, msg, after=None, parent=None, size=256, interval=10):
        QStackedWidget.__init__(self, parent)
        self.wp = WaitPanel(msg, self, size, interval)
        if after is None:
            after = QWidget(self)
        self.after = after
        self.addWidget(self.wp)
        self.addWidget(after)

    def start(self):
        self.setCurrentWidget(self.wp)
        self.wp.start()

    def stop(self):
        self.wp.stop()
        self.setCurrentWidget(self.after)

if __name__ == '__main__':
    from calibre.gui2 import Application
    app = Application([])
    d = QDialog()
    d.resize(100, 100)
    w = ProgressSpinner(d)
    l = QVBoxLayout(d)
    l.addWidget(w)
    w.start()
    d.exec_()
    del d
    del app