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()
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()
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 identical CSS rules')) 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.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) d.l.addWidget(d.bb) d.bb.rejected.connect(d.reject) d.bb.accepted.connect(d.accept) if d.exec_() != d.Accepted: raise Abort() ans['remove_unused_classes'] = tprefs['remove_unused_classes'] = c.isChecked() ans['merge_identical_selectors'] = tprefs['merge_identical_selectors'] = m.isChecked()
def createWordDialog(self, word=Word('')): dialog = QDialog(self) layout = QGridLayout(self) dialog.setLayout(layout) shortEdit = QLineEdit(word.short) longEdit = QLineEdit(word.long) explainEdit = QLineEdit(word.explain) okButton = QPushButton('OK') okButton.clicked.connect(dialog.accept) cancelButton = QPushButton('Cancel') cancelButton.clicked.connect(dialog.reject) layout.addWidget(QLabel('Short'), 0, 0) layout.addWidget(shortEdit, 0, 1) layout.addWidget(QLabel('Long'), 1, 0) layout.addWidget(longEdit, 1, 1) layout.addWidget(QLabel('Translate'), 2, 0) layout.addWidget(explainEdit, 2, 1) layout.addWidget(okButton, 3, 0) layout.addWidget(cancelButton, 3, 1) dialog.exec() if (dialog.result() == QDialog.Accepted): word = Word( '%s,%s,%s' % (shortEdit.text(), longEdit.text(), explainEdit.text())) self.dictionary.append(word) self.dictionary.save() self.updateTable(self.dictionary.words)
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()
def get_bulk_rename_settings(parent, number, msg=None, sanitize=sanitize_file_name_unicode, leading_zeros=True, prefix=None, category='text'): # {{{ d = QDialog(parent) d.setWindowTitle(_('Bulk rename items')) d.l = l = QFormLayout(d) d.setLayout(l) d.prefix = p = QLineEdit(d) prefix = prefix or {k:v for k, __, v in CATEGORIES}.get(category, _('Chapter-')) 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) d.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(d.accept), bb.rejected.connect(d.reject) l.addRow(bb) if d.exec_() == d.Accepted: prefix = sanitize(unicode(d.prefix.text())) num = d.num.value() fmt = '%d' if leading_zeros: largest = num + number - 1 fmt = '%0{0}d'.format(len(str(largest))) return prefix + fmt, num return None, None
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) d.show_changes = False if changed: b = d.b = d.bb.addButton(_('See what &changed'), d.bb.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'), 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() if d.show_changes: show_current_diff(allow_revert=True)
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()
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()
def run(self, *args, **kwargs): """Create & show dialog Args: onClose(accepted): Function to run on close. Defaults to None. """ dlg = QDialog() dlg.setWindowFlags(dlg.windowFlags() & ~Qt.WindowContextHelpButtonHint) dlg.setWindowTitle(title) layout = QVBoxLayout() layout.setContentsMargins(10, 10, 10, 10) self.layout = layout dlg.setLayout(layout) pushQDlgStack(self) self.constructor(dlg, *args, **kwargs) popQDlgStack(self) dlg.setWindowModality(Qt.WindowModal) if size: dlg.resize(size[0], size[1]) dlg.show() return dlg.exec_() == QDialog.Accepted
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()
def test(): app = QApplication([]) app d = QDialog() d.setLayout(QVBoxLayout()) d.layout().addWidget(FontFamilyChooser(d)) d.layout().addWidget(QFontComboBox(d)) d.exec_()
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()
def get_bulk_rename_settings(parent, number, msg=None, sanitize=sanitize_file_name_unicode, 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.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(d.accept), bb.rejected.connect(d.reject) l.addRow(bb) ans = {'prefix': None, 'start': None} if d.exec_() == d.Accepted: prefix = sanitize(unicode(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 = '%0{0}d'.format(len(str(largest))) ans['prefix'] = prefix + fmt ans['start'] = num if allow_spine_order: ans['spine_order'] = d.spine_order.isChecked() return ans
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_type(d.url.text()).strip(), unicode_type( d.name.text()).strip() is_image = d.treat_as_image.isChecked() return link, name, is_image
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()
def link_stylesheets(self, names): s = self.categories['styles'] sheets = [ unicode(s.child(i).data(0, NAME_ROLE) or '') for i in xrange(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(self.InternalMove) s.setAutoScroll(True) s.setDefaultDropAction(Qt.MoveAction) for name in sheets: i = QListWidgetItem(name, s) flags = Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled | Qt.ItemIsSelectable i.setFlags(flags) i.setCheckState(Qt.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.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(d.accept), bb.rejected.connect(d.reject) l.addWidget(bb) if d.exec_() == d.Accepted: tprefs['remove_existing_links_when_linking_sheets'] = r.isChecked() sheets = [ unicode(s.item(il).text()) for il in xrange(s.count()) if s.item(il).checkState() == Qt.Checked ] if sheets: self.link_stylesheets_requested.emit(names, sheets, r.isChecked())
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
def customize_recipe(self): d = QDialog(self) d.l = QVBoxLayout() d.setLayout(d.l) d.list = QListWidget(d) connect_lambda(d.list.doubleClicked, d, lambda d: 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_type(item.data(Qt.UserRole) or '') title = unicode_type(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') src = as_unicode(src) self.edit_recipe(None, src)
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)
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_()
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.Close) bb.accepted.connect(d.accept) bb.rejected.connect(d.reject) l.addWidget(bb) bb.addButton(_('Copy to clipboard'), bb.ActionRole) bb.clicked.connect( lambda: QApplication.clipboard().setText(v.toPlainText())) d.exec_()
def get_bulk_rename_settings(parent, number, msg=None, sanitize=sanitize_file_name_unicode, 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.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(d.accept), bb.rejected.connect(d.reject) l.addRow(bb) ans = {'prefix': None, 'start': None} if d.exec_() == d.Accepted: prefix = sanitize(unicode(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 = '%0{0}d'.format(len(str(largest))) ans['prefix'] = prefix + fmt ans['start'] = num if allow_spine_order: ans['spine_order'] = d.spine_order.isChecked() return ans
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.Close) bb.accepted.connect(d.accept) bb.rejected.connect(d.reject) l.addWidget(bb) bb.addButton(_('Copy to clipboard'), bb.ActionRole) bb.clicked.connect(lambda : QApplication.clipboard().setText(v.toPlainText())) d.exec_()
def customize_remove_unused_css(name, parent, ans): d = QDialog(parent) d.l = l = QVBoxLayout() d.setLayout(d.l) d.setWindowTitle(_('Remove unused CSS')) d.la = la = QLabel(_( 'This will remove all CSS rules that do not match any actual content. You' ' can also have it automatically remove any class attributes from the HTML' ' that do not match any CSS rules, by using the check box below:')) la.setWordWrap(True), l.addWidget(la) d.c = c = QCheckBox(_('Remove unused &class attributes')) c.setChecked(tprefs['remove_unused_classes']) l.addWidget(c) d.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) d.l.addWidget(d.bb) d.bb.rejected.connect(d.reject) d.bb.accepted.connect(d.accept) if d.exec_() != d.Accepted: raise Abort() ans['remove_unused_classes'] = tprefs['remove_unused_classes'] = c.isChecked()
def link_stylesheets(self, names): s = self.categories["styles"] sheets = [unicode(s.child(i).data(0, NAME_ROLE) or "") for i in xrange(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(self.InternalMove) s.setAutoScroll(True) s.setDefaultDropAction(Qt.MoveAction) for name in sheets: i = QListWidgetItem(name, s) flags = Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled | Qt.ItemIsSelectable i.setFlags(flags) i.setCheckState(Qt.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.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(d.accept), bb.rejected.connect(d.reject) l.addWidget(bb) if d.exec_() == d.Accepted: tprefs["remove_existing_links_when_linking_sheets"] = r.isChecked() sheets = [unicode(s.item(il).text()) for il in xrange(s.count()) if s.item(il).checkState() == Qt.Checked] if sheets: self.link_stylesheets_requested.emit(names, sheets, r.isChecked())
def customize_remove_unused_css(name, parent, ans): d = QDialog(parent) d.l = l = QVBoxLayout() d.setLayout(d.l) d.setWindowTitle(_('Remove unused CSS')) d.la = la = QLabel( _('This will remove all CSS rules that do not match any actual content. You' ' can also have it automatically remove any class attributes from the HTML' ' that do not match any CSS rules, by using the check box below:')) la.setWordWrap(True), l.addWidget(la) d.c = c = QCheckBox(_('Remove unused &class attributes')) c.setChecked(tprefs['remove_unused_classes']) l.addWidget(c) d.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) d.l.addWidget(d.bb) d.bb.rejected.connect(d.reject) d.bb.accepted.connect(d.accept) if d.exec_() != d.Accepted: raise Abort() ans['remove_unused_classes'] = tprefs[ 'remove_unused_classes'] = c.isChecked()
def update(self, sim_data_items): """Adds all elements in the iterable *sim_data_items* to the tree or replaces them if they are already present. Issues the *items_changed* signal, after all sim data items are added/replaced. :param sim_data_items: Iterable collection of :class: `SimDataItem`s to be added """ additional_param_found = [] all_enc_configs = {} diff_dict = {} # build up a diff dict in order let the software handle multiple different parameters # in one simulation directory # some of the diffs should not be interpreted as parameters # those are removed from the dict; for sure QP, RealFormat, InternalFormat, and Warning # are not parameters # if you want to simulate with your own parameters, make sure that they appear in the # logfile try: for sim_data_item in sim_data_items: if sim_data_item.__class__ not in all_enc_configs: all_enc_configs[sim_data_item.__class__] = [] diff_dict[sim_data_item.__class__] = {} all_enc_configs[sim_data_item.__class__].append( sim_data_item.encoder_config) # print(sim_data_item.summary_data['encoder_config']) value_filter = ['.yuv', '.bin', '.hevc', '.jem'] key_filter = [] for sim_class in all_enc_configs.keys(): for i in range(len(all_enc_configs[sim_class]) - 1): current_item, next_item = all_enc_configs[sim_class][ i], all_enc_configs[sim_class][i + 1] diff = set(current_item.values()) ^ set(next_item.values()) for (key, value) in set(current_item.items()) ^ set( next_item.items()): if all(y not in key for y in key_filter): if all(x not in value for x in value_filter): if key not in diff_dict[sim_class]: diff_dict[sim_class][key] = [] diff_dict[sim_class][key].append(value) else: if value not in diff_dict[sim_class][key]: diff_dict[sim_class][key].append(value) # dialog window which displays all parameters with varying values in a list # the user can drag the parameters, he wants to analyse further into an other list # the order of the parameters in the list determines the order of the parameter tree if diff_dict[sim_class]: par_list = [ item for item in diff_dict[sim_class] if item != 'QP' ] qp_item = QtWidgets.QListWidgetItem('QP') chosen_par = QtWidgets.QListWidget() chosen_par.addItem(qp_item) chosen_par.setDragDropMode(QAbstractItemView.DragDrop) chosen_par.setDefaultDropAction(QtCore.Qt.MoveAction) not_chosen_par = QtWidgets.QListWidget() not_chosen_par.addItems(par_list) not_chosen_par.setDragDropMode(QAbstractItemView.DragDrop) not_chosen_par.setDefaultDropAction(QtCore.Qt.MoveAction) if len(diff_dict[sim_class]) > 1: main_layout = QVBoxLayout() dialog = QDialog() dialog.setWindowTitle('Choose Parameters') dialog.setLayout(main_layout) msg = QtWidgets.QLabel() msg.setText( 'Additional Parameters have been found.\n' 'Move Parameters you want to consider further to the right list.\n' ) main_layout.addWidget(msg) list_layout = QHBoxLayout() main_layout.addLayout(list_layout) # TODO: all items dragged into chosen_par should appear above the qp_item list_layout.addWidget(not_chosen_par) list_layout.addWidget(chosen_par) not_chosen_par.show() chosen_par.show() ok_button = QPushButton('OK') main_layout.addWidget(ok_button) ok_button.clicked.connect(dialog.close) dialog.exec() for i in range(len(not_chosen_par)): diff_dict[sim_class].pop( not_chosen_par.item(i).text(), None) additional_param_found.append(sim_class) except (AttributeError): # maybe do something useful here # This is for conformance with rd data written out by older versions of rdplot pass for sim_data_item in sim_data_items: has_additional_params = False if sim_data_item.__class__ in additional_param_found: sim_data_item.additional_params = [ chosen_par.item(i).text() for i in range(len(chosen_par)) ] has_additional_params = True # Get *item* of the tree corresponding to *sim_data_item* item = self.create_path(*sim_data_item.tree_identifier_list) # This prevents an sim data item overwriting another one # with same *tree_identifier_list* but different absolute path for value in item.values: condition = (value.tree_identifier_list == sim_data_item.tree_identifier_list and value.path != sim_data_item.path and not has_additional_params) if condition: raise AmbiguousSimDataItems( ("Ambigious sim data items: Sim Data Item {} and {}" " have different absolute paths but the same" " position at the tree {}").format( sim_data_item, value, AbstractEncLog.tree_identifier_list)) # Add *sim_data_item* to the set of values of the tree item *item* item.values.add(sim_data_item) self.items_changed.emit()
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
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
dev = self.parent().device_manager.connected_device dev.highlight_ignored_folders = True self.parent().configure_connected_device() dev.highlight_ignored_folders = False if __name__ == '__main__': from calibre.gui2 import Application from calibre.devices.mtp.driver import MTP_DEVICE from calibre.devices.scanner import DeviceScanner s = DeviceScanner() s.scan() app = Application([]) dev = MTP_DEVICE(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.Ok|QDialogButtonBox.Cancel) d.l.addWidget(bb) bb.accepted.connect(d.accept) bb.rejected.connect(d.reject) if d.exec_() == d.Accepted: cw.commit() dev.shutdown()
def exec_(self): dialog = QDialog(self.parent) textEdit = QTextEdit(dialog) buttonBox = QDialogButtonBox(dialog) layout = QVBoxLayout(dialog) labels = [] html = '' width = 400 height = 25 def triggeredCredit(): if textEdit.isVisible(): for i in range(2 if self.logo else 1, len(labels)): labels[i].show() textEdit.hide() else: for i in range(2 if self.logo else 1, len(labels)): labels[i].hide() textEdit.show() def triggeredClose(arg): dialog.close() dialog.setWindowTitle('About {}'.format(self.programName)) for key in self.__labelsKeys: value = self.__labels.get(key) if value: label = QLabel(dialog) label.setAlignment(Qt.AlignCenter) if key == 'website' or key == 'license': label.setText('<a href="{}">{}</a>'.format( value['url'], value['label'] if value['label'] else value['url'])) label.setTextFormat(Qt.RichText) label.setTextInteractionFlags(Qt.TextBrowserInteraction) label.setOpenExternalLinks(True) elif key == 'logo': image = QPixmap(self.logo) label.setPixmap(image.scaled(128, 128)) else: label.setText(value) labels.append(label) layout.addWidget(labels[len(labels) - 1]) for key in self.__creditsKeys: value = self.__credits.get(key) if len(value.get('contributors')) > 0: html += '<p><strong>{}</strong><br />{}</p>'.format( value.get('label'), '<br />'.join(value.get('contributors'))) if html: textEdit.setHtml('<center>{}</center>'.format(html)) layout.addWidget(textEdit) buttonBox.addButton( 'Credits', QDialogButtonBox.YesRole).clicked.connect(triggeredCredit) textEdit.close() textEdit.setReadOnly(True) buttonBox.addButton( 'Close', QDialogButtonBox.NoRole).clicked.connect(triggeredClose) layout.addWidget(buttonBox) dialog.setLayout(layout) height *= len(dialog.children()) if self.logo: height += 128 dialog.setFixedSize(width, height) return dialog.exec_()
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 == e.FocusOut: if c.isVisible(): return True return EnComboBox.eventFilter(self, obj, e) if __name__ == '__main__': from PyQt5.Qt import QDialog, QVBoxLayout from calibre.gui2 import Application app = Application([]) d = QDialog() d.setLayout(QVBoxLayout()) le = EditWithComplete(d) d.layout().addWidget(le) items = [ 'one', 'otwo', 'othree', 'ooone', 'ootwo', 'other', 'odd', 'over', 'orc', 'oven', 'owe', 'oothree', 'a1', 'a2', u'Edgas', u'Èdgar', u'Édgaq', u'Edgar', u'Édgar' ] le.update_items_cache(items) le.show_initial_value('') d.exec_()
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_() == d.Accepted: cw.commit() dev.shutdown()
def textChanged(self): return self.lineEdit().textChanged def clear(self): self.lineEdit().clear() 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 == e.FocusOut: if c.isVisible(): return True return EnComboBox.eventFilter(self, obj, e) if __name__ == '__main__': from PyQt5.Qt import QDialog, QVBoxLayout app = QApplication([]) d = QDialog() d.setLayout(QVBoxLayout()) le = EditWithComplete(d) d.layout().addWidget(le) items = ['one', 'otwo', 'othree', 'ooone', 'ootwo', 'oothree', 'a1', 'a2',u'Edgas', u'Èdgar', u'Édgaq', u'Edgar', u'Édgar'] le.update_items_cache(items) le.show_initial_value('') d.exec_()