def __init__(self, parent, icon, text, over=True): QDialog.__init__(self, parent) self.state=None layout = QVBoxLayout(self) self.setLayout(layout) self.setWindowTitle('UnMerge Epub') label = QLabel(text) label.setOpenExternalLinks(True) label.setWordWrap(True) layout.addWidget(label) button_box = QDialogButtonBox(self) button = button_box.addButton(_("Add"), button_box.AcceptRole) button.clicked.connect(self.add) if over: button = button_box.addButton(_("Overwrite"), button_box.AcceptRole) button.clicked.connect(self.over) button = button_box.addButton(_("Discard"), button_box.AcceptRole) button.clicked.connect(self.discard) button_box.accepted.connect(self.accept) layout.addWidget(button_box)
class ConfirmDialog(QDialog): def __init__(self, ids, parent): QDialog.__init__(self, parent) self.setWindowTitle(_('Schedule download?')) self.setWindowIcon(QIcon(I('dialog_question.png'))) l = self.l = QGridLayout() self.setLayout(l) i = QLabel(self) i.setPixmap(QPixmap(I('dialog_question.png'))) l.addWidget(i, 0, 0) t = QLabel( '<p>'+_('The download of metadata for the <b>%d selected book(s)</b> will' ' run in the background. Proceed?')%len(ids) + '<p>'+_('You can monitor the progress of the download ' 'by clicking the rotating spinner in the bottom right ' 'corner.') + '<p>'+_('When the download completes you will be asked for' ' confirmation before calibre applies the downloaded metadata.') ) t.setWordWrap(True) l.addWidget(t, 0, 1) l.setColumnStretch(0, 1) l.setColumnStretch(1, 100) self.identify = self.covers = True self.bb = QDialogButtonBox(QDialogButtonBox.Cancel) self.bb.rejected.connect(self.reject) b = self.bb.addButton(_('Download only &metadata'), self.bb.AcceptRole) b.clicked.connect(self.only_metadata) b.setIcon(QIcon(I('edit_input.png'))) b = self.bb.addButton(_('Download only &covers'), self.bb.AcceptRole) b.clicked.connect(self.only_covers) b.setIcon(QIcon(I('default_cover.png'))) b = self.b = self.bb.addButton(_('&Configure download'), self.bb.ActionRole) b.setIcon(QIcon(I('config.png'))) b.clicked.connect(partial(show_config, parent, self)) l.addWidget(self.bb, 1, 0, 1, 2) b = self.bb.addButton(_('Download &both'), self.bb.AcceptRole) b.clicked.connect(self.accept) b.setDefault(True) b.setAutoDefault(True) b.setIcon(QIcon(I('ok.png'))) self.resize(self.sizeHint()) b.setFocus(Qt.OtherFocusReason) def only_metadata(self): self.covers = False self.accept() def only_covers(self): self.identify = False self.accept()
def _init_controls(self): layout = QVBoxLayout(self) self.setLayout(layout) ml = QHBoxLayout() layout.addLayout(ml, 1) self.keys_list = QListWidget(self) self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection) self.keys_list.setFixedWidth(150) self.keys_list.setAlternatingRowColors(True) ml.addWidget(self.keys_list) self.value_text = QTextEdit(self) self.value_text.setTabStopWidth(24) self.value_text.setReadOnly(False) ml.addWidget(self.value_text, 1) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self._apply_changes) button_box.rejected.connect(self.reject) self.clear_button = button_box.addButton('Clear', QDialogButtonBox.ResetRole) self.clear_button.setIcon(get_icon('trash.png')) self.clear_button.setToolTip('Clear all settings for this plugin') self.clear_button.clicked.connect(self._clear_settings) layout.addWidget(button_box)
def __init__(self, parent, icon, text, over=True): QDialog.__init__(self, parent) self.state=None layout = QVBoxLayout(self) self.setLayout(layout) self.setWindowTitle(_('UnMerge Epub')) label = QLabel(text) label.setOpenExternalLinks(True) label.setWordWrap(True) layout.addWidget(label) self.applyall = QCheckBox(_('Apply to all EPUBs?'),self) self.applyall.setToolTip(_('Apply the same action to the rest of the EPUBs after this.')) layout.addWidget(self.applyall) button_box = QDialogButtonBox(self) button = button_box.addButton(_("Add"), button_box.AcceptRole) button.clicked.connect(self.add) if over: button = button_box.addButton(_("Overwrite"), button_box.AcceptRole) button.clicked.connect(self.over) button = button_box.addButton(_("Discard"), button_box.AcceptRole) button.clicked.connect(self.discard) button_box.accepted.connect(self.accept) layout.addWidget(button_box)
class UpdateNotification(QDialog): def __init__(self, calibre_version, plugin_updates, parent=None): QDialog.__init__(self, parent) self.setAttribute(Qt.WA_QuitOnClose, False) self.resize(400, 250) self.l = QGridLayout() self.setLayout(self.l) self.logo = QLabel() self.logo.setMaximumWidth(110) self.logo.setPixmap(QPixmap(I('lt.png')).scaled(100, 100, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) ver = calibre_version if ver.endswith('.0'): ver = ver[:-2] self.label = QLabel(('<p>'+ _('New version <b>%(ver)s</b> of %(app)s is available for download. ' 'See the <a href="http://calibre-ebook.com/whats-new' '">new features</a>.'))%dict( app=__appname__, ver=ver)) self.label.setOpenExternalLinks(True) self.label.setWordWrap(True) self.setWindowTitle(_('Update available!')) self.setWindowIcon(QIcon(I('lt.png'))) self.l.addWidget(self.logo, 0, 0) self.l.addWidget(self.label, 0, 1) self.cb = QCheckBox( _('Show this notification for future updates'), self) self.l.addWidget(self.cb, 1, 0, 1, -1) self.cb.setChecked(config.get('new_version_notification')) self.cb.stateChanged.connect(self.show_future) self.bb = QDialogButtonBox(self) b = self.bb.addButton(_('&Get update'), self.bb.AcceptRole) b.setDefault(True) b.setIcon(QIcon(I('arrow-down.png'))) if plugin_updates > 0: b = self.bb.addButton(_('Update &plugins'), self.bb.ActionRole) b.setIcon(QIcon(I('plugins/plugin_updater.png'))) b.clicked.connect(self.get_plugins, type=Qt.QueuedConnection) self.bb.addButton(self.bb.Cancel) self.l.addWidget(self.bb, 2, 0, 1, -1) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) dynamic.set('update to version %s'%calibre_version, False) def get_plugins(self): from calibre.gui2.dialogs.plugin_updater import (PluginUpdaterDialog, FILTER_UPDATE_AVAILABLE) d = PluginUpdaterDialog(self.parent(), initial_filter=FILTER_UPDATE_AVAILABLE) d.exec_() def show_future(self, *args): config.set('new_version_notification', bool(self.cb.isChecked())) def accept(self): open_url(QUrl(get_download_url())) QDialog.accept(self)
def __init__(self, gui, interface_action, books): ''' :param gui: Parent gui :param interface_action: InterfaceActionObject (InterfacePluginAction class from action.py) :param books: list of Kobo book ''' self.books = books self.gui = gui self.interface_action = interface_action self.books = books SizePersistedDialog.__init__(self, gui, PLUGIN_NAME + 'plugin:selections dialog') self.setWindowTitle(_(PLUGIN_NAME + ' v' + PLUGIN_VERSION)) self.setMinimumWidth(300) self.setMinimumHeight(300) layout = QVBoxLayout(self) self.setLayout(layout) title_layout = ImageTitleLayout(self, 'images/obok.png', _('Obok DeDRM')) layout.addLayout(title_layout) help_label = QLabel(_('<a href="http://www.foo.com/">Help</a>'), self) help_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard) help_label.setAlignment(Qt.AlignRight) help_label.linkActivated.connect(self._help_link_activated) title_layout.addWidget(help_label) title_layout.setAlignment(Qt.AlignTop) layout.addSpacing(5) main_layout = QHBoxLayout() layout.addLayout(main_layout) # self.listy = QListWidget() # self.listy.setSelectionMode(QAbstractItemView.ExtendedSelection) # main_layout.addWidget(self.listy) # self.listy.addItems(books) self.books_table = BookListTableWidget(self) main_layout.addWidget(self.books_table) layout.addSpacing(10) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self._ok_clicked) button_box.rejected.connect(self.reject) self.select_all_button = button_box.addButton(_("Select All"), QDialogButtonBox.ResetRole) self.select_all_button.setToolTip(_("Select all books to add them to the calibre library.")) self.select_all_button.clicked.connect(self._select_all_clicked) self.select_drm_button = button_box.addButton(_("All with DRM"), QDialogButtonBox.ResetRole) self.select_drm_button.setToolTip(_("Select all books with DRM.")) self.select_drm_button.clicked.connect(self._select_drm_clicked) self.select_free_button = button_box.addButton(_("All DRM free"), QDialogButtonBox.ResetRole) self.select_free_button.setToolTip(_("Select all books without DRM.")) self.select_free_button.clicked.connect(self._select_free_clicked) layout.addWidget(button_box) # Cause our dialog size to be restored from prefs or created on first usage self.resize_dialog() self.books_table.populate_table(self.books)
class MovedDialog(QDialog): # {{{ def __init__(self, stats, location, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(_("No library found")) self._l = l = QGridLayout(self) self.setLayout(l) self.stats, self.location = stats, location loc = self.oldloc = location.replace("/", os.sep) self.header = QLabel( _( "No existing calibre library was found at %s. " "If the library was moved, select its new location below. " "Otherwise calibre will forget this library." ) % loc ) self.header.setWordWrap(True) ncols = 2 l.addWidget(self.header, 0, 0, 1, ncols) self.cl = QLabel("<br><b>" + _("New location of this library:")) l.addWidget(self.cl, 1, 0, 1, ncols) self.loc = QLineEdit(loc, self) l.addWidget(self.loc, 2, 0, 1, 1) self.cd = QToolButton(self) self.cd.setIcon(QIcon(I("document_open.png"))) self.cd.clicked.connect(self.choose_dir) l.addWidget(self.cd, 2, 1, 1, 1) self.bb = QDialogButtonBox(QDialogButtonBox.Abort) b = self.bb.addButton(_("Library moved"), self.bb.AcceptRole) b.setIcon(QIcon(I("ok.png"))) b = self.bb.addButton(_("Forget library"), self.bb.RejectRole) b.setIcon(QIcon(I("edit-clear.png"))) b.clicked.connect(self.forget_library) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) l.addWidget(self.bb, 3, 0, 1, ncols) self.resize(self.sizeHint() + QSize(100, 50)) def choose_dir(self): d = choose_dir(self, "library moved choose new loc", _("New library location"), default_dir=self.oldloc) if d is not None: self.loc.setText(d) def forget_library(self): self.stats.remove(self.location) def accept(self): newloc = unicode(self.loc.text()) if not db_class().exists_at(newloc): error_dialog(self, _("No library found"), _("No existing calibre library found at %s") % newloc, show=True) return self.stats.rename(self.location, newloc) self.newloc = newloc QDialog.accept(self)
class ImportAnnotationsDialog(QDialog): def __init__(self, parent, friendly_name, rac): #self.dialog = QDialog(parent.gui) QDialog.__init__(self, parent.gui) self.parent = parent self.opts = parent.opts self.rac = rac parent_loc = self.parent.gui.pos() self.move(parent_loc.x(), parent_loc.y()) self.setWindowTitle(rac.import_dialog_title) self.setWindowIcon(self.opts.icon) l = QVBoxLayout() self.setLayout(l) self.pte = PlainTextEdit(self.parent) self.pte.setPlainText(rac.initial_dialog_text) self.pte.setMinimumWidth(400) l.addWidget(self.pte) self.dialogButtonBox = QDialogButtonBox(QDialogButtonBox.Cancel|QDialogButtonBox.Help) self.import_button = self.dialogButtonBox.addButton(self.dialogButtonBox.Ok) self.import_button.setText('Import') self.dialogButtonBox.clicked.connect(self.import_annotations_dialog_clicked) l.addWidget(self.dialogButtonBox) self.rejected.connect(self.close) self.exec_() self.text = str(self.pte.toPlainText()) def close(self): # Catch ESC and close button self.pte.setPlainText('') self.accept() def import_annotations_dialog_clicked(self, button): BUTTON_ROLES = ['AcceptRole', 'RejectRole', 'DestructiveRole', 'ActionRole', 'HelpRole', 'YesRole', 'NoRole', 'ApplyRole', 'ResetRole'] if self.dialogButtonBox.buttonRole(button) == QDialogButtonBox.AcceptRole: # Remove initial_dialog_text if user clicks OK without dropping file if self.text() == self.rac.initial_dialog_text: self.pte.clear() self.accept() elif self.dialogButtonBox.buttonRole(button) == QDialogButtonBox.HelpRole: hv = HelpView(self, self.opts.icon, self.opts.prefs, html=self.rac.import_help_text) hv.show() else: self.close() def text(self): return unicode(self.pte.toPlainText())
class DebugDevice(QDialog): def __init__(self, gui, parent=None): QDialog.__init__(self, parent) self.gui = gui self._layout = QVBoxLayout(self) self.setLayout(self._layout) self.log = QPlainTextEdit(self) self._layout.addWidget(self.log) self.log.setPlainText(_('Getting debug information, please wait')+'...') self.copy = QPushButton(_('Copy to &clipboard')) self.copy.setDefault(True) self.setWindowTitle(_('Debug device detection')) self.setWindowIcon(QIcon(I('debug.png'))) self.copy.clicked.connect(self.copy_to_clipboard) self.ok = QPushButton('&OK') self.ok.setAutoDefault(False) self.ok.clicked.connect(self.accept) self.bbox = QDialogButtonBox(self) self.bbox.addButton(self.copy, QDialogButtonBox.ActionRole) self.bbox.addButton(self.ok, QDialogButtonBox.AcceptRole) self._layout.addWidget(self.bbox) self.resize(750, 500) self.bbox.setEnabled(False) QTimer.singleShot(1000, self.debug) def debug(self): if self.gui.device_manager.is_device_connected: error_dialog(self, _('Device already detected'), _('A device (%s) is already detected by calibre.' ' If you wish to debug the detection of another device' ', first disconnect this device.')% self.gui.device_manager.connected_device.get_gui_name(), show=True) self.bbox.setEnabled(True) return self.gui.debug_detection(self) def __call__(self, job): if not self.isVisible(): return self.bbox.setEnabled(True) if job.failed: return error_dialog(self, _('Debugging failed'), _('Running debug device detection failed. Click Show ' 'Details for more information.'), det_msg=job.details, show=True) self.log.setPlainText(job.result) def copy_to_clipboard(self): QApplication.clipboard().setText(self.log.toPlainText())
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 __init__(self, book_mi, annotations, parent=None): #QDialog.__init__(self, parent) self.prefs = plugin_prefs super(PreviewDialog, self).__init__(parent, 'annotations_preview_dialog') self.pl = QVBoxLayout(self) self.setLayout(self.pl) self.label = QLabel() self.label.setText("<b>%s annotations · %s</b>" % (book_mi.reader_app, book_mi.title)) self.label.setAlignment(Qt.AlignHCenter) self.pl.addWidget(self.label) self.wv = QWebView() self.wv.setHtml(annotations) self.pl.addWidget(self.wv) self.buttonbox = QDialogButtonBox(QDialogButtonBox.Close) # self.buttonbox.addButton('Close', QDialogButtonBox.AcceptRole) self.buttonbox.setOrientation(Qt.Horizontal) # self.buttonbox.accepted.connect(self.close) self.buttonbox.rejected.connect(self.close) # self.connect(self.buttonbox, pyqtSignal('accepted()'), self.close) # self.connect(self.buttonbox, pyqtSignal('rejected()'), self.close) self.pl.addWidget(self.buttonbox) # Sizing sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) self.resize_dialog()
def __init__(self, stats, location, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(_('No library found')) self._l = l = QGridLayout(self) self.setLayout(l) self.stats, self.location = stats, location loc = self.oldloc = location.replace('/', os.sep) self.header = QLabel(_('No existing calibre library was found at %s. ' 'If the library was moved, select its new location below. ' 'Otherwise calibre will forget this library.')%loc) self.header.setWordWrap(True) ncols = 2 l.addWidget(self.header, 0, 0, 1, ncols) self.cl = QLabel('<br><b>'+_('New location of this library:')) l.addWidget(self.cl, 1, 0, 1, ncols) self.loc = QLineEdit(loc, self) l.addWidget(self.loc, 2, 0, 1, 1) self.cd = QToolButton(self) self.cd.setIcon(QIcon(I('document_open.png'))) self.cd.clicked.connect(self.choose_dir) l.addWidget(self.cd, 2, 1, 1, 1) self.bb = QDialogButtonBox(QDialogButtonBox.Abort) b = self.bb.addButton(_('Library moved'), self.bb.AcceptRole) b.setIcon(QIcon(I('ok.png'))) b = self.bb.addButton(_('Forget library'), self.bb.RejectRole) b.setIcon(QIcon(I('edit-clear.png'))) b.clicked.connect(self.forget_library) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) l.addWidget(self.bb, 3, 0, 1, ncols) self.resize(self.sizeHint() + QSize(100, 50))
def __init__(self, current_cover=None, parent=None): QDialog.__init__(self, parent) self.current_cover = current_cover self.log = Log() self.cover_pixmap = None self.setWindowTitle(_('Downloading cover...')) self.setWindowIcon(QIcon(I('default_cover.png'))) self.l = l = QVBoxLayout() self.setLayout(l) self.covers_widget = CoversWidget(self.log, self.current_cover, parent=self) self.covers_widget.chosen.connect(self.accept) l.addWidget(self.covers_widget) self.resize(850, 600) self.finished.connect(self.cleanup) self.bb = QDialogButtonBox(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) l.addWidget(self.bb) self.log_button = self.bb.addButton(_('&View log'), self.bb.ActionRole) self.log_button.clicked.connect(self.view_log) self.log_button.setIcon(QIcon(I('debug.png'))) self.bb.rejected.connect(self.reject) self.bb.accepted.connect(self.accept) geom = gprefs.get('single-cover-fetch-dialog-geometry', None) if geom is not None: self.restoreGeometry(geom)
def __init__(self, title, html, parent=None): ''' :param title: Caption for window title :param html: HTML string log/report ''' QDialog.__init__(self, parent) self.l = l = QVBoxLayout() self.setLayout(l) self.tb = QTextBrowser(self) QApplication.setOverrideCursor(Qt.WaitCursor) # Rather than formatting the text in <pre> blocks like the calibre # ViewLog does, instead just format it inside divs to keep style formatting html = html.replace('\t',' ')#.replace('\n', '<br/>') html = html.replace('> ','> ') self.tb.setHtml('<div>{0}</div>'.format(html)) QApplication.restoreOverrideCursor() l.addWidget(self.tb) self.bb = QDialogButtonBox(QDialogButtonBox.Ok) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.copy_button = self.bb.addButton(_('Copy to clipboard'), self.bb.ActionRole) self.copy_button.setIcon(QIcon(I('edit-copy.png'))) self.copy_button.clicked.connect(self.copy_to_clipboard) l.addWidget(self.bb) self.setModal(False) self.resize(QSize(700, 500)) self.setWindowTitle(title) self.setWindowIcon(QIcon(I('dialog_information.png'))) self.show()
class ViewLog(QDialog): # {{{ def __init__(self, title, html, parent=None): QDialog.__init__(self, parent) self.l = l = QVBoxLayout() self.setLayout(l) self.tb = QTextBrowser(self) self.tb.setHtml('<pre style="font-family: monospace">%s</pre>' % html) l.addWidget(self.tb) self.bb = QDialogButtonBox(QDialogButtonBox.Ok) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.copy_button = self.bb.addButton(_('Copy to clipboard'), self.bb.ActionRole) self.copy_button.setIcon(QIcon(I('edit-copy.png'))) self.copy_button.clicked.connect(self.copy_to_clipboard) l.addWidget(self.bb) self.setModal(False) self.resize(QSize(700, 500)) self.setWindowTitle(title) self.setWindowIcon(QIcon(I('debug.png'))) self.show() def copy_to_clipboard(self): txt = self.tb.toPlainText() QApplication.clipboard().setText(txt)
def __init__(self, log, parent=None): QDialog.__init__(self, parent) self.log = log self.l = l = QVBoxLayout() self.setLayout(l) self.tb = QTextBrowser(self) l.addWidget(self.tb) self.bb = QDialogButtonBox(QDialogButtonBox.Close) l.addWidget(self.bb) self.copy_button = self.bb.addButton(_('Copy to clipboard'), self.bb.ActionRole) self.copy_button.clicked.connect(self.copy_to_clipboard) self.copy_button.setIcon(QIcon(I('edit-copy.png'))) self.bb.rejected.connect(self.reject) self.bb.accepted.connect(self.accept) self.setWindowTitle(_('Download log')) self.setWindowIcon(QIcon(I('debug.png'))) self.resize(QSize(800, 400)) self.keep_updating = True self.last_html = None self.finished.connect(self.stop) QTimer.singleShot(100, self.update_log) self.show()
def __init__(self, parent, friendly_name, rac): #self.dialog = QDialog(parent.gui) QDialog.__init__(self, parent.gui) self.parent = parent self.opts = parent.opts self.rac = rac parent_loc = self.parent.gui.pos() self.move(parent_loc.x(), parent_loc.y()) self.setWindowTitle(rac.import_dialog_title) self.setWindowIcon(self.opts.icon) l = QVBoxLayout() self.setLayout(l) self.pte = PlainTextEdit(self.parent) self.pte.setPlainText(rac.initial_dialog_text) self.pte.setMinimumWidth(400) l.addWidget(self.pte) self.dialogButtonBox = QDialogButtonBox(QDialogButtonBox.Cancel|QDialogButtonBox.Help) self.import_button = self.dialogButtonBox.addButton(self.dialogButtonBox.Ok) self.import_button.setText('Import') self.dialogButtonBox.clicked.connect(self.import_annotations_dialog_clicked) l.addWidget(self.dialogButtonBox) self.rejected.connect(self.close) self.exec_() self.text = str(self.pte.toPlainText())
def __init__(self, title, html, parent=None, unique_name=None): QDialog.__init__(self, parent) self.l = l = QVBoxLayout() self.setLayout(l) self.tb = QTextBrowser(self) self.tb.setHtml('<pre style="font-family: monospace">%s</pre>' % html) l.addWidget(self.tb) self.bb = QDialogButtonBox(QDialogButtonBox.Ok) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.copy_button = self.bb.addButton(_('Copy to clipboard'), self.bb.ActionRole) self.copy_button.setIcon(QIcon(I('edit-copy.png'))) self.copy_button.clicked.connect(self.copy_to_clipboard) l.addWidget(self.bb) self.unique_name = unique_name or 'view-log-dialog' self.finished.connect(self.dialog_closing) self.resize(QSize(700, 500)) geom = gprefs.get(self.unique_name, None) if geom is not None: self.restoreGeometry(geom) self.setModal(False) self.setWindowTitle(title) self.setWindowIcon(QIcon(I('debug.png'))) self.show()
def __init__(self, parent): QWidget.__init__(self, parent) self.setVisible(False) parent.installEventFilter(self) self._show_fraction = 0.0 self.show_animation = a = QPropertyAnimation(self, "show_fraction", self) a.setDuration(1000), a.setEasingCurve(QEasingCurve.OutQuad) a.setStartValue(0.0), a.setEndValue(1.0) a.finished.connect(self.stop_show_animation) self.rendered_pixmap = None self.questions = [] self.icon = ic = Icon(self) self.msg_label = msg = QLabel("some random filler text") msg.setWordWrap(True) self.bb = QDialogButtonBox() self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.log_button = self.bb.addButton(_("View log"), self.bb.ActionRole) self.log_button.setIcon(QIcon(I("debug.png"))) self.log_button.clicked.connect(self.show_log) self.copy_button = self.bb.addButton(_("&Copy to clipboard"), self.bb.ActionRole) self.copy_button.clicked.connect(self.copy_to_clipboard) self.action_button = self.bb.addButton("", self.bb.ActionRole) self.action_button.clicked.connect(self.action_clicked) self.show_det_msg = _("Show &details") self.hide_det_msg = _("Hide &details") self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole) self.det_msg_toggle.clicked.connect(self.toggle_det_msg) self.det_msg_toggle.setToolTip(_("Show detailed information about this error")) self.det_msg = PlainTextEdit(self) self.det_msg.setReadOnly(True) self.bb.setStandardButtons(self.bb.Yes | self.bb.No | self.bb.Ok) self.bb.button(self.bb.Yes).setDefault(True) self.title_label = title = QLabel("A dummy title") f = title.font() f.setBold(True) title.setFont(f) self.checkbox = QCheckBox("", self) self._l = l = QVBoxLayout(self) self._h = h = QHBoxLayout() self._v = v = QVBoxLayout() v.addWidget(title), v.addWidget(msg) h.addWidget(ic), h.addSpacing(10), h.addLayout(v), l.addLayout(h) l.addSpacing(5) l.addWidget(self.checkbox) l.addWidget(self.det_msg) l.addWidget(self.bb) self.ask_question.connect(self.do_ask_question, type=Qt.QueuedConnection) self.setFocusPolicy(Qt.NoFocus) for child in self.findChildren(QWidget): child.setFocusPolicy(Qt.NoFocus) self.setFocusProxy(self.parent()) self.resize_timer = t = QTimer(self) t.setSingleShot(True), t.setInterval(100), t.timeout.connect(self.parent_resized)
def setup_ui(self): self.l = l = QGridLayout(self) self.bb = QDialogButtonBox(self) self.bb.setStandardButtons(self.bb.Cancel) self.bb.rejected.connect(self.reject) self.la1 = la = QLabel('<h2>' + self.title) l.addWidget(la, 0, 0, 1, -1) self.la2 = la = QLabel(_('Total:')) l.addWidget(la, l.rowCount(), 0) self.overall = p = QProgressBar(self) p.setMinimum(0), p.setValue(0), p.setMaximum(0) p.setMinimumWidth(450) l.addWidget(p, l.rowCount()-1, 1) self.omsg = la = QLabel(self) la.setMaximumWidth(450) l.addWidget(la, l.rowCount(), 1) self.la3 = la = QLabel(_('Current:')) l.addWidget(la, l.rowCount(), 0) self.current = p = QProgressBar(self) p.setMinimum(0), p.setValue(0), p.setMaximum(0) l.addWidget(p, l.rowCount()-1, 1) self.cmsg = la = QLabel(self) la.setMaximumWidth(450) l.addWidget(la, l.rowCount(), 1) l.addWidget(self.bb, l.rowCount(), 0, 1, -1) self.update_current_signal.connect(self.update_current, type=Qt.QueuedConnection) self.update_overall_signal.connect(self.update_overall, type=Qt.QueuedConnection) self.finish_signal.connect(self.finish_processing, type=Qt.QueuedConnection)
class CoverFetch(QDialog): # {{{ def __init__(self, current_cover=None, parent=None): QDialog.__init__(self, parent) self.current_cover = current_cover self.log = Log() self.cover_pixmap = None self.setWindowTitle(_('Downloading cover...')) self.setWindowIcon(QIcon(I('default_cover.png'))) self.l = l = QVBoxLayout() self.setLayout(l) self.covers_widget = CoversWidget(self.log, self.current_cover, parent=self) self.covers_widget.chosen.connect(self.accept) l.addWidget(self.covers_widget) self.resize(850, 600) self.finished.connect(self.cleanup) self.bb = QDialogButtonBox(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) l.addWidget(self.bb) self.log_button = self.bb.addButton(_('&View log'), self.bb.ActionRole) self.log_button.clicked.connect(self.view_log) self.log_button.setIcon(QIcon(I('debug.png'))) self.bb.rejected.connect(self.reject) self.bb.accepted.connect(self.accept) geom = gprefs.get('single-cover-fetch-dialog-geometry', None) if geom is not None: self.restoreGeometry(geom) def cleanup(self): self.covers_widget.cleanup() def reject(self): gprefs.set('single-cover-fetch-dialog-geometry', bytearray(self.saveGeometry())) self.covers_widget.cancel() return QDialog.reject(self) def accept(self, *args): gprefs.set('single-cover-fetch-dialog-geometry', bytearray(self.saveGeometry())) self.cover_pixmap = self.covers_widget.cover_pixmap() QDialog.accept(self) def start(self, title, authors, identifiers): book = Metadata(title, authors) book.identifiers = identifiers self.covers_widget.start(book, self.current_cover, title, authors, {}) return self.exec_() def view_log(self): self._lv = LogViewer(self.log, self)
def __init__(self, ids, parent): QDialog.__init__(self, parent) self.setWindowTitle(_("Schedule download?")) self.setWindowIcon(QIcon(I("download-metadata.png"))) l = self.l = QGridLayout() self.setLayout(l) i = QLabel(self) i.setPixmap(QPixmap(I("download-metadata.png"))) l.addWidget(i, 0, 0) t = QLabel( "<p>" + _("The download of metadata for the <b>%d selected book(s)</b> will" " run in the background. Proceed?") % len(ids) + "<p>" + _( "You can monitor the progress of the download " "by clicking the rotating spinner in the bottom right " "corner." ) + "<p>" + _( "When the download completes you will be asked for" " confirmation before calibre applies the downloaded metadata." ) ) t.setWordWrap(True) l.addWidget(t, 0, 1) l.setColumnStretch(0, 1) l.setColumnStretch(1, 100) self.identify = self.covers = True self.bb = QDialogButtonBox(QDialogButtonBox.Cancel) self.bb.rejected.connect(self.reject) b = self.bb.addButton(_("Download only &metadata"), self.bb.AcceptRole) b.clicked.connect(self.only_metadata) b.setIcon(QIcon(I("edit_input.png"))) b = self.bb.addButton(_("Download only &covers"), self.bb.AcceptRole) b.clicked.connect(self.only_covers) b.setIcon(QIcon(I("default_cover.png"))) b = self.b = self.bb.addButton(_("&Configure download"), self.bb.ActionRole) b.setIcon(QIcon(I("config.png"))) b.clicked.connect(partial(show_config, parent, self)) l.addWidget(self.bb, 1, 0, 1, 2) b = self.bb.addButton(_("Download &both"), self.bb.AcceptRole) b.clicked.connect(self.accept) b.setDefault(True) b.setAutoDefault(True) b.setIcon(QIcon(I("ok.png"))) self.resize(self.sizeHint()) b.setFocus(Qt.OtherFocusReason)
class Wizard(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) self.resize(440, 480) self.verticalLayout = QVBoxLayout(self) self.widget = WizardWidget(self) self.verticalLayout.addWidget(self.widget) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) self.verticalLayout.addWidget(self.buttonBox) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.setModal(Qt.WindowModal) @property def xpath(self): return self.widget.xpath
def __init__(self, current_family, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(_('Choose font family')) self.setWindowIcon(QIcon(I('font.png'))) from calibre.utils.fonts.scanner import font_scanner self.font_scanner = font_scanner self.m = QStringListModel(self) self.build_font_list() self.l = l = QGridLayout() self.setLayout(l) self.view = FontsView(self) self.view.setModel(self.m) self.view.setCurrentIndex(self.m.index(0)) if current_family: for i, val in enumerate(self.families): if icu_lower(val) == icu_lower(current_family): self.view.setCurrentIndex(self.m.index(i)) break self.view.doubleClicked.connect(self.accept, type=Qt.QueuedConnection) self.view.changed.connect(self.current_changed, type=Qt.QueuedConnection) self.faces = Typefaces(self) self.bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.add_fonts_button = afb = self.bb.addButton(_('Add &fonts'), self.bb.ActionRole) afb.setIcon(QIcon(I('plus.png'))) afb.clicked.connect(self.add_fonts) self.ml = QLabel(_('Choose a font family from the list below:')) self.search = QLineEdit(self) self.search.setPlaceholderText(_('Search')) self.search.returnPressed.connect(self.find) self.nb = QToolButton(self) self.nb.setIcon(QIcon(I('arrow-down.png'))) self.nb.setToolTip(_('Find next')) self.pb = QToolButton(self) self.pb.setIcon(QIcon(I('arrow-up.png'))) self.pb.setToolTip(_('Find previous')) self.nb.clicked.connect(self.find_next) self.pb.clicked.connect(self.find_previous) l.addWidget(self.ml, 0, 0, 1, 4) l.addWidget(self.search, 1, 0, 1, 1) l.addWidget(self.nb, 1, 1, 1, 1) l.addWidget(self.pb, 1, 2, 1, 1) l.addWidget(self.view, 2, 0, 1, 3) l.addWidget(self.faces, 1, 3, 2, 1) l.addWidget(self.bb, 3, 0, 1, 4) l.setAlignment(self.faces, Qt.AlignTop) self.resize(800, 600)
def __init__(self, gui, icon, do_user_config): QDialog.__init__(self, gui) self.gui = gui self.do_user_config = do_user_config self.db = gui.current_db self.l = QVBoxLayout() self.setLayout(self.l) self.setWindowTitle('Wiki Reader') self.setWindowIcon(icon) self.helpl = QLabel( 'Enter the URL of a wikipedia article below. ' 'It will be downloaded and converted into an ebook.') self.helpl.setWordWrap(True) self.l.addWidget(self.helpl) self.w = QWidget(self) self.sa = QScrollArea(self) self.l.addWidget(self.sa) self.w.l = QVBoxLayout() self.w.setLayout(self.w.l) self.sa.setWidget(self.w) self.sa.setWidgetResizable(True) self.title = Title(self) self.w.l.addWidget(self.title) self.urls = [URL(self)] self.w.l.addWidget(self.urls[0]) self.add_more_button = QPushButton( QIcon(I('plus.png')), 'Add another URL') self.l.addWidget(self.add_more_button) self.bb = QDialogButtonBox(self) self.bb.setStandardButtons(self.bb.Ok | self.bb.Cancel) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.l.addWidget(self.bb) self.book_button = b = self.bb.addButton( 'Convert a Wiki&Book', self.bb.ActionRole) b.clicked.connect(self.wiki_book) self.add_more_button.clicked.connect(self.add_more) self.finished.connect(self.download) self.setMinimumWidth(500) self.resize(self.sizeHint()) self.single_url = None
def __init__(self, gui, header, prefs, icon, lines, do_split_fn, do_splits_fn, get_split_size_fn, do_user_config, save_size_name='epubsplit:update list dialog'): SizePersistedDialog.__init__(self, gui, save_size_name) self.gui = gui self.do_split_fn = do_split_fn self.do_splits_fn = do_splits_fn self.get_split_size_fn = get_split_size_fn self.do_user_config = do_user_config self.prefs = prefs self.setWindowTitle(header) self.setWindowIcon(icon) layout = QVBoxLayout(self) self.setLayout(layout) title_layout = ImageTitleLayout(self, 'images/icon.png', header) layout.addLayout(title_layout) lines_layout = QHBoxLayout() layout.addLayout(lines_layout) self.lines_table = LinesTableWidget(self) lines_layout.addWidget(self.lines_table) options_layout = QHBoxLayout() # Button to search the document for something config_button = QtGui.QPushButton(_('Configure'),self) config_button.clicked.connect(self.user_config) config_button.setToolTip(_('Configure Plugin')) options_layout.addWidget(config_button) button_box = QDialogButtonBox(self) new_book = button_box.addButton(_("New Book"), button_box.ActionRole) new_book.setToolTip(_("Make <i>one</i> new book containing the sections selected above and then edit its Metadata.")) new_book.clicked.connect(self.new_book) new_books = button_box.addButton(_("New Book per Section"), button_box.ActionRole) new_books.setToolTip(_("Make a new book for <i>each</i> of the sections selected above. Title for each will be the Table of Contents, which you can edit here first.")) new_books.clicked.connect(self.new_books) get_split_size = button_box.addButton(_("Get Size"), button_box.ActionRole) get_split_size.setToolTip("<i></i>" + _("Calculate the size of the new book from the currently selected sections.")) get_split_size.clicked.connect(self.get_split_size) button_box.addButton(_("Done"), button_box.RejectRole) button_box.rejected.connect(self.reject) options_layout.addWidget(button_box) layout.addLayout(options_layout) # Cause our dialog size to be restored from prefs or created on first usage self.resize_dialog() self.lines_table.populate_table(lines) self.lines_table.show_checkedalways(self.prefs['show_checkedalways'])
def __init__(self, current_cover=None, parent=None): QDialog.__init__(self, parent) self.current_cover = current_cover self.log = Log() self.book = self.cover_pixmap = None self.setWindowTitle(_("Downloading metadata...")) self.setWindowIcon(QIcon(I("download-metadata.png"))) self.stack = QStackedWidget() self.l = l = QVBoxLayout() self.setLayout(l) l.addWidget(self.stack) self.bb = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) l.addWidget(self.bb) self.bb.rejected.connect(self.reject) self.bb.accepted.connect(self.accept) self.next_button = self.bb.addButton(_("Next"), self.bb.ActionRole) self.next_button.setDefault(True) self.next_button.setEnabled(False) self.next_button.setIcon(QIcon(I("ok.png"))) self.next_button.clicked.connect(self.next_clicked) self.ok_button = self.bb.button(self.bb.Ok) self.ok_button.setEnabled(False) self.ok_button.clicked.connect(self.ok_clicked) self.prev_button = self.bb.addButton(_("Back"), self.bb.ActionRole) self.prev_button.setIcon(QIcon(I("back.png"))) self.prev_button.clicked.connect(self.back_clicked) self.log_button = self.bb.addButton(_("View log"), self.bb.ActionRole) self.log_button.clicked.connect(self.view_log) self.log_button.setIcon(QIcon(I("debug.png"))) self.prev_button.setVisible(False) self.identify_widget = IdentifyWidget(self.log, self) self.identify_widget.rejected.connect(self.reject) self.identify_widget.results_found.connect(self.identify_results_found) self.identify_widget.book_selected.connect(self.book_selected) self.stack.addWidget(self.identify_widget) self.covers_widget = CoversWidget(self.log, self.current_cover, parent=self) self.covers_widget.chosen.connect(self.ok_clicked) self.stack.addWidget(self.covers_widget) self.resize(850, 600) geom = gprefs.get("metadata_single_gui_geom", None) if geom is not None and geom: self.restoreGeometry(geom) self.finished.connect(self.cleanup)
def __init__(self, parent): QDialog.__init__(self, parent) self.setAttribute(Qt.WA_DeleteOnClose, False) self.setWindowIcon(QIcon(I('dialog_question.png'))) self.questions = [] self._l = l = QGridLayout(self) self.setLayout(l) self.icon_label = ic = QLabel(self) ic.setPixmap(QPixmap(I('dialog_question.png'))) self.msg_label = msg = QLabel('some random filler text') msg.setWordWrap(True) ic.setMaximumWidth(110) ic.setMaximumHeight(100) ic.setScaledContents(True) ic.setStyleSheet('QLabel { margin-right: 10px }') self.bb = QDialogButtonBox() self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.log_button = self.bb.addButton(_('View log'), self.bb.ActionRole) self.log_button.setIcon(QIcon(I('debug.png'))) self.log_button.clicked.connect(self.show_log) self.copy_button = self.bb.addButton(_('&Copy to clipboard'), self.bb.ActionRole) self.copy_button.clicked.connect(self.copy_to_clipboard) self.action_button = self.bb.addButton('', self.bb.ActionRole) self.action_button.clicked.connect(self.action_clicked) self.show_det_msg = _('Show &details') self.hide_det_msg = _('Hide &details') self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole) self.det_msg_toggle.clicked.connect(self.toggle_det_msg) self.det_msg_toggle.setToolTip( _('Show detailed information about this error')) self.det_msg = QPlainTextEdit(self) self.det_msg.setReadOnly(True) self.bb.setStandardButtons(self.bb.Yes|self.bb.No|self.bb.Ok) self.bb.button(self.bb.Yes).setDefault(True) self.checkbox = QCheckBox('', self) l.addWidget(ic, 0, 0, 1, 1) l.addWidget(msg, 0, 1, 1, 1) l.addWidget(self.checkbox, 1, 0, 1, 2) l.addWidget(self.det_msg, 2, 0, 1, 2) l.addWidget(self.bb, 3, 0, 1, 2) self.ask_question.connect(self.do_ask_question, type=Qt.QueuedConnection)
def _init_controls(self): layout = QVBoxLayout(self) self.setLayout(layout) ml = QHBoxLayout() layout.addLayout(ml, 1) self.keys_list = QListWidget(self) self.keys_list.setSelectionMode(QAbstractItemView.SingleSelection) self.keys_list.setFixedWidth(150) self.keys_list.setAlternatingRowColors(True) ml.addWidget(self.keys_list) self.value_text = QTextEdit(self) self.value_text.setTabStopWidth(24) self.value_text.setReadOnly(True) ml.addWidget(self.value_text, 1) button_box = QDialogButtonBox(QDialogButtonBox.Ok) button_box.accepted.connect(self.accept) self.clear_button = button_box.addButton(_('Clear'), QDialogButtonBox.ResetRole) self.clear_button.setIcon(get_icon('trash.png')) self.clear_button.setToolTip(_('Clear all settings for this plugin')) self.clear_button.clicked.connect(self._clear_settings) if DEBUG: self.edit_button = button_box.addButton(_('Edit'), QDialogButtonBox.ResetRole) self.edit_button.setIcon(get_icon('edit_input.png')) self.edit_button.setToolTip(_('Edit settings.')) self.edit_button.clicked.connect(self._edit_settings) self.save_button = button_box.addButton(_('Save'), QDialogButtonBox.ResetRole) self.save_button.setIcon(get_icon('save.png')) self.save_button.setToolTip(_('Save setting for this plugin')) self.save_button.clicked.connect(self._save_settings) self.save_button.setEnabled(False) layout.addWidget(button_box)
def __init__(self, parent): QDialog.__init__(self, parent) self.setAttribute(Qt.WA_DeleteOnClose, False) self.queue = [] self.do_pop.connect(self.pop, type=Qt.QueuedConnection) self._layout = l = QGridLayout() self.setLayout(l) self.icon = QIcon(I('dialog_error.png')) self.setWindowIcon(self.icon) self.icon_label = QLabel() self.icon_label.setPixmap(self.icon.pixmap(68, 68)) self.icon_label.setMaximumSize(QSize(68, 68)) self.msg_label = QLabel('<p> ') self.msg_label.setStyleSheet('QLabel { margin-top: 1ex; }') self.msg_label.setWordWrap(True) self.msg_label.setTextFormat(Qt.RichText) self.det_msg = QPlainTextEdit(self) self.det_msg.setVisible(False) self.bb = QDialogButtonBox(QDialogButtonBox.Close, parent=self) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.ctc_button = self.bb.addButton(_('&Copy to clipboard'), self.bb.ActionRole) self.ctc_button.clicked.connect(self.copy_to_clipboard) self.retry_button = self.bb.addButton(_('&Retry'), self.bb.ActionRole) self.retry_button.clicked.connect(self.retry) self.retry_func = None self.show_det_msg = _('Show &details') self.hide_det_msg = _('Hide &details') self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole) self.det_msg_toggle.clicked.connect(self.toggle_det_msg) self.det_msg_toggle.setToolTip( _('Show detailed information about this error')) self.suppress = QCheckBox(self) l.addWidget(self.icon_label, 0, 0, 1, 1) l.addWidget(self.msg_label, 0, 1, 1, 1) l.addWidget(self.det_msg, 1, 0, 1, 2) l.addWidget(self.suppress, 2, 0, 1, 2, Qt.AlignLeft|Qt.AlignBottom) l.addWidget(self.bb, 3, 0, 1, 2, Qt.AlignRight|Qt.AlignBottom) l.setColumnStretch(1, 100) self.setModal(False) self.suppress.setVisible(False) self.do_resize()
def __init__(self, parent): QDialog.__init__(self, parent) self.setWindowTitle(_('Add a dictionary website')) self.l = l = QFormLayout(self) self.la = la = QLabel('<p>' + _( 'Choose a language and enter the website address (URL) for it below.' ' The URL must have the placeholder <b>%s</b> in it, which will be replaced by the actual word being' ' looked up') % '{word}') la.setWordWrap(True) l.addRow(la) self.le = LanguagesEdit(self) l.addRow(_('&Language:'), self.le) self.url = u = QLineEdit(self) u.setMinimumWidth(350) u.setPlaceholderText( _('For example: %s') % 'https://dictionary.com/{word}') l.addRow(_('&URL:'), u) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) l.addRow(bb) bb.accepted.connect(self.accept), bb.rejected.connect( self.reject) self.resize(self.sizeHint())
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)
def __init__(self, parent, duplicates, loc): QDialog.__init__(self, parent) l = QVBoxLayout() self.setLayout(l) self.la = la = QLabel( _('Books with the same, title, author and language as the following already exist in the library %s.' ' Select which books you want copied anyway.') % os.path.basename(loc)) la.setWordWrap(True) l.addWidget(la) self.setWindowTitle(_('Duplicate books')) self.books = QListWidget(self) self.items = [] for book_id, (title, authors) in iteritems(duplicates): i = QListWidgetItem( _('{0} by {1}').format(title, ' & '.join(authors[:3])), self.books) i.setData(Qt.ItemDataRole.UserRole, book_id) i.setFlags(Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsEnabled) i.setCheckState(Qt.CheckState.Checked) self.items.append(i) l.addWidget(self.books) self.bb = bb = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.a = b = bb.addButton(_('Select &all'), bb.ActionRole) b.clicked.connect(self.select_all), b.setIcon(QIcon(I('plus.png'))) self.n = b = bb.addButton(_('Select &none'), bb.ActionRole) b.clicked.connect(self.select_none), b.setIcon(QIcon(I('minus.png'))) self.ctc = b = bb.addButton(_('&Copy to clipboard'), bb.ActionRole) b.clicked.connect(self.copy_to_clipboard), b.setIcon( QIcon(I('edit-copy.png'))) l.addWidget(bb) self.resize(600, 400)
def __init__(self, fmt_count, msg, single=False, parent=None, exclude=False): QDialog.__init__(self, parent) self._l = QVBoxLayout(self) self.single_fmt = single self.setLayout(self._l) self.setWindowTitle(_('Choose formats')) self._m = QLabel(msg) self._m.setWordWrap(True) self._l.addWidget(self._m) self.formats = Formats(fmt_count) self.fview = QListView(self) self.fview.doubleClicked.connect(self.double_clicked, type=Qt.QueuedConnection) if exclude: self.fview.setStyleSheet(''' QListView { background-color: #FAE7B5} ''') self._l.addWidget(self.fview) self.fview.setModel(self.formats) self.fview.setSelectionMode(self.fview.SingleSelection if single else self.fview.MultiSelection) self.bbox = \ QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel, Qt.Horizontal, self) self._l.addWidget(self.bbox) self.bbox.accepted.connect(self.accept) self.bbox.rejected.connect(self.reject) self.fview.setIconSize(QSize(48, 48)) self.fview.setSpacing(2) self.resize(350, 500) self.selected_formats = set([])
def __init__(self, msg, name, parent, config_set=dynamic, icon='dialog_warning.png', title=None, confirm_msg=None, show_cancel_button=True): QDialog.__init__(self, parent) self.setWindowTitle(title or _("Are you sure?")) self.setWindowIcon(QIcon(I(icon))) self.l = l = QVBoxLayout(self) self.h = h = QHBoxLayout() l.addLayout(h) self.icon_widget = Icon(self) self.icon_widget.set_icon(QIcon(I(icon))) self.msg = m = QLabel(self) m.setOpenExternalLinks(True) m.setMinimumWidth(350), m.setWordWrap(True), m.setObjectName("msg") m.setText(msg) h.addWidget(self.icon_widget), h.addSpacing(10), h.addWidget(m) self.again = a = QCheckBox((confirm_msg or _("&Show this warning again")), self) a.setChecked(True), a.setObjectName("again") a.stateChanged.connect(self.toggle) l.addWidget(a) buttons = QDialogButtonBox.Ok if show_cancel_button: buttons |= QDialogButtonBox.Cancel self.buttonBox = bb = QDialogButtonBox(buttons, self) bb.setObjectName("buttonBox") bb.setFocus(Qt.OtherFocusReason) bb.accepted.connect(self.accept), bb.rejected.connect(self.reject) l.addWidget(bb) self.name = name self.config_set = config_set self.resize(self.sizeHint())
def __init__(self, pdfpath, parent=None): QDialog.__init__(self, parent) self.pdfpath = pdfpath self.l = l = QGridLayout() self.setLayout(l) self.la = la = QLabel( _('Choose a cover from the list of PDF pages below')) l.addWidget(la) self.loading = la = QLabel('<b>' + _('Rendering PDF pages, please wait...')) l.addWidget(la) self.covers = c = QListWidget(self) l.addWidget(c) self.item_delegate = CoverDelegate(self) c.setItemDelegate(self.item_delegate) c.setIconSize(QSize(120, 160)) c.setSelectionMode(c.SingleSelection) c.setViewMode(c.IconMode) c.setUniformItemSizes(True) c.setResizeMode(c.Adjust) c.itemDoubleClicked.connect(self.accept) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) l.addWidget(bb) self.rendering_done.connect(self.show_pages, type=Qt.QueuedConnection) self.tdir = PersistentTemporaryDirectory('_pdf_covers') self.thread = Thread(target=self.render) self.thread.daemon = True self.thread.start() self.setWindowTitle(_('Choose cover from PDF')) self.setWindowIcon(file_icon_provider().icon_from_ext('pdf')) self.resize(QSize(800, 600))
def __init__(self, title=None, parent=None): QDialog.__init__(self, parent) 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))
def __init__(self, pdfpath, parent=None): QDialog.__init__(self, parent) self.pdfpath = pdfpath self.stack = WaitLayout(_('Rendering PDF pages, please wait...'), parent=self) self.container = self.stack.after self.container.l = l = QVBoxLayout(self.container) self.la = la = QLabel( _('Choose a cover from the list of PDF pages below')) l.addWidget(la) self.covers = c = QListWidget(self) l.addWidget(c) self.item_delegate = CoverDelegate(self) c.setItemDelegate(self.item_delegate) c.setIconSize(QSize(120, 160)) c.setSelectionMode(c.SingleSelection) c.setViewMode(c.IconMode) c.setUniformItemSizes(True) c.setResizeMode(c.Adjust) c.itemDoubleClicked.connect(self.accept, type=Qt.QueuedConnection) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.more_pages = b = bb.addButton(_('&More pages'), QDialogButtonBox.ActionRole) b.clicked.connect(self.start_rendering) l.addWidget(bb) self.rendering_done.connect(self.show_pages, type=Qt.QueuedConnection) self.first = 1 self.setWindowTitle(_('Choose cover from PDF')) self.setWindowIcon(file_icon_provider().icon_from_ext('pdf')) self.resize(QSize(800, 600)) self.tdir = PersistentTemporaryDirectory('_pdf_covers') self.start_rendering()
class ViewLog(QDialog): # {{{ def __init__(self, title, html, parent=None, unique_name=None): QDialog.__init__(self, parent) self.l = l = QVBoxLayout() self.setLayout(l) self.tb = QTextBrowser(self) self.tb.setHtml('<pre style="font-family: monospace">%s</pre>' % html) l.addWidget(self.tb) self.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.copy_button = self.bb.addButton(_('Copy to clipboard'), self.bb.ActionRole) self.copy_button.setIcon(QIcon(I('edit-copy.png'))) self.copy_button.clicked.connect(self.copy_to_clipboard) l.addWidget(self.bb) self.unique_name = unique_name or 'view-log-dialog' self.finished.connect(self.dialog_closing) self.resize(QSize(700, 500)) geom = gprefs.get(self.unique_name, None) if geom is not None: QApplication.instance().safe_restore_geometry(self, geom) self.setModal(False) self.setWindowTitle(title) self.setWindowIcon(QIcon(I('debug.png'))) self.show() def copy_to_clipboard(self): txt = self.tb.toPlainText() QApplication.clipboard().setText(txt) def dialog_closing(self, result): gprefs[self.unique_name] = bytearray(self.saveGeometry())
def __init__(self, window, msg, formats, show_open_with=False): QDialog.__init__(self, window) self.resize(507, 377) self.setWindowIcon(QIcon(I("mimetypes/unknown.png"))) self.setWindowTitle(_('Choose Format')) self.l = l = QVBoxLayout(self) self.msg = QLabel(msg) l.addWidget(self.msg) self.formats = QListWidget(self) self.formats.setIconSize(QSize(64, 64)) self.formats.activated[QModelIndex].connect(self.activated_slot) l.addWidget(self.formats) self.h = h = QHBoxLayout() h.setContentsMargins(0, 0, 0, 0) l.addLayout(h) if show_open_with: self.owb = QPushButton(_('&Open With...'), self) h.addWidget(self.owb) self.own = QMenu(self.owb.text()) self.owb.setMenu(self.own) self.own.aboutToShow.connect(self.populate_open_with) self.buttonBox = bb = QDialogButtonBox(self) bb.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(self.accept), bb.rejected.connect(self.reject) h.addStretch(10), h.addWidget(self.buttonBox) for format in formats: self.formats.addItem( QListWidgetItem( file_icon_provider().icon_from_ext(format.lower()), format.upper())) self._formats = formats self.formats.setCurrentRow(0) self._format = self.open_with_format = None if show_open_with: self.populate_open_with()
def initialize_controls(self, title, initial_value): self.setWindowTitle('Lock Series Index') layout = QVBoxLayout(self) self.setLayout(layout) title_layout = ImageTitleLayout(self, 'images/lock32.png', 'Lock Series Index') layout.addLayout(title_layout) layout.addSpacing(10) self.title_label = QLabel('Series index for book: \'%s\'' % title, self) layout.addWidget(self.title_label) hlayout = QHBoxLayout() layout.addLayout(hlayout) self.value_spinbox = QDoubleSpinBox(self) self.value_spinbox.setRange(0, 99000000) self.value_spinbox.setDecimals(2) if initial_value is not None: self.value_spinbox.setValue(initial_value) self.value_spinbox.selectAll() hlayout.addWidget(self.value_spinbox, 0) hlayout.addStretch(1) self.assign_same_checkbox = QCheckBox( '&Assign this index value to all remaining books', self) layout.addWidget(self.assign_same_checkbox) layout.addStretch(1) # Dialog buttons button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) layout.addWidget(button_box)
def setup_ui(self): self.resize(678, 430) self.setWindowTitle(_("Add books by ISBN")) self.setWindowIcon(QIcon(I('add_book.png'))) self.l = l = QVBoxLayout(self) self.h = h = QHBoxLayout() l.addLayout(h) self.bb = bb = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self) bb.button(bb.Ok).setShortcut(QKeySequence(Qt.Key_O | Qt.ALT)) l.addWidget(bb), bb.accepted.connect(self.accept), bb.rejected.connect( self.reject) self.ll = l = QVBoxLayout() h.addLayout(l) self.isbn_box = i = QPlainTextEdit(self) l.addWidget(i) self.paste_button = b = QPushButton(_("&Paste from clipboard"), self) l.addWidget(b), b.clicked.connect(self.paste) self.lll = l = QVBoxLayout() h.addLayout(l) self.label = la = QLabel( _("<p>Enter a list of ISBNs in the box to the left, one per line. calibre will automatically" " create entries for books based on the ISBN and download metadata and covers for them.</p>\n" "<p>Any invalid ISBNs in the list will be ignored.</p>\n" "<p>You can also specify a file that will be added with each ISBN. To do this enter the full" " path to the file after a <code>>></code>. For example:</p>\n" "<p><code>9788842915232 >> %s</code></p>"), self) l.addWidget(la), la.setWordWrap(True) l.addSpacing(20) self.la2 = la = QLabel(_("&Tags to set on created book entries:"), self) l.addWidget(la) self.add_tags = le = QLineEdit(self) la.setBuddy(le) l.addWidget(le) l.addStretch(10)
def __init__(self, names, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(_('Choose master file')) self.l = l = QVBoxLayout() self.setLayout(l) self.la = la = QLabel(_('Choose the master file. All selected files will be merged into the master file:')) la.setWordWrap(True) l.addWidget(la) self.sa = sa = QScrollArea(self) l.addWidget(sa) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) l.addWidget(bb) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.w = w = QWidget(self) w.l = QVBoxLayout() w.setLayout(w.l) buttons = self.buttons = [QRadioButton(n) for n in names] buttons[0].setChecked(True) map(w.l.addWidget, buttons) sa.setWidget(w) self.resize(self.sizeHint() + QSize(150, 20))
def __init__(self, width, height, parent=None): QDialog.__init__(self, parent) self.l = l = QFormLayout(self) self.setLayout(l) self.aspect_ratio = width / float(height) l.addRow(QLabel(_('Choose the new width and height'))) self._width = w = QSpinBox(self) w.setMinimum(1) w.setMaximum(10 * width) w.setValue(width) w.setSuffix(' px') l.addRow(_('&Width:'), w) self._height = h = QSpinBox(self) h.setMinimum(1) h.setMaximum(10 * height) h.setValue(height) h.setSuffix(' px') l.addRow(_('&Height:'), h) connect_lambda(w.valueChanged, self, lambda self: self.keep_ar('width')) connect_lambda(h.valueChanged, self, lambda self: self.keep_ar('height')) self.ar = ar = QCheckBox(_('Keep &aspect ratio')) ar.setChecked(True) l.addRow(ar) self.resize(self.sizeHint()) self.bb = bb = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) l.addRow(bb)
def __init__(self, formats, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(_('Choose format to edit')) self.setWindowIcon(QIcon(I('dialog_question.png'))) l = self.l = QGridLayout() self.setLayout(l) la = self.la = QLabel(_('Choose which format you want to edit:')) formats = sorted(formats) l.addWidget(la, 0, 0, 1, -1) self.buttons = [] for i, f in enumerate(formats): b = QCheckBox('&' + f, self) l.addWidget(b, 1, i) self.buttons.append(b) self.formats = gprefs.get('edit_toc_last_selected_formats', ['EPUB',]) bb = self.bb = QDialogButtonBox( QDialogButtonBox.Ok|QDialogButtonBox.Cancel) bb.addButton(_('&All formats'), bb.ActionRole).clicked.connect(self.do_all) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) l.addWidget(bb, l.rowCount(), 0, 1, -1) self.resize(self.sizeHint()) connect_lambda(self.finished, self, lambda self, code:gprefs.set('edit_toc_last_selected_formats', list(self.formats)))
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.Close) self.b = bb.addButton(_('Configure'), bb.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())
class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName(_fromUtf8("Dialog")) Dialog.resize(497, 235) self.gridLayout = QGridLayout(Dialog) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.icon_label = QLabel(Dialog) self.icon_label.setMaximumSize( QtCore.QSize(COVER_ICON_SIZE, COVER_ICON_SIZE)) self.icon_label.setText(_fromUtf8("")) self.icon_label.setPixmap(QPixmap(_fromUtf8(I("dialog_warning.png")))) self.icon_label.setScaledContents(False) self.icon_label.setObjectName(_fromUtf8("icon_label")) self.gridLayout.addWidget(self.icon_label, 0, 0, 1, 1) self.msg = QLabel(Dialog) self.msg.setText(_fromUtf8("")) self.msg.setWordWrap(True) self.msg.setOpenExternalLinks(True) self.msg.setObjectName(_fromUtf8("msg")) self.gridLayout.addWidget(self.msg, 0, 1, 1, 1) self.det_msg = QPlainTextEdit(Dialog) self.det_msg.setReadOnly(True) self.det_msg.setObjectName(_fromUtf8("det_msg")) self.gridLayout.addWidget(self.det_msg, 1, 0, 1, 2) self.bb = QDialogButtonBox(Dialog) self.bb.setOrientation(QtCore.Qt.Horizontal) self.bb.setStandardButtons(QDialogButtonBox.Ok) self.bb.setObjectName(_fromUtf8("bb")) self.gridLayout.addWidget(self.bb, 3, 0, 1, 2) self.toggle_checkbox = QCheckBox(Dialog) self.toggle_checkbox.setText(_fromUtf8("")) self.toggle_checkbox.setObjectName(_fromUtf8("toggle_checkbox")) self.gridLayout.addWidget(self.toggle_checkbox, 2, 0, 1, 2) self.retranslateUi(Dialog) self.bb.accepted.connect(Dialog.accept) self.bb.rejected.connect(Dialog.reject) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): Dialog.setWindowTitle(_("Dialog"))
def setup_ui(self): self.setMinimumWidth(300) self.setMinimumHeight(300) layout = QVBoxLayout(self) self.setLayout(layout) main_layout = QHBoxLayout() layout.addLayout(main_layout) self.listy = QListWidget() # self.listy.setSelectionMode(QAbstractItemView.ExtendedSelection) main_layout.addWidget(self.listy) self.listy.addItems(self.files) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box = QDialogButtonBox() ok_button = button_box.addButton(_("See what changed"), QDialogButtonBox.AcceptRole) cancel_button = button_box.addButton(_("Close"), QDialogButtonBox.RejectRole) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) layout.addWidget(button_box)
class Preferences(QDialog): """docstring for Preferences.""" def __init__(self, parent): super(Preferences, self).__init__(parent) self.layout = QVBoxLayout(self) self.tab = QTabWidget(self) self.themeChooser = ThemeChooser(self.tab) self.tab.addTab(self.themeChooser, 'Theme') self.saveOption = SaveOption(self.tab, self.parent().saveThreading) self.tab.addTab(self.saveOption, 'Save') self.layout.addWidget(self.tab) self.buttonBox = QDialogButtonBox(self) self.buttonBox.addButton('Ok', QDialogButtonBox.AcceptRole) self.buttonBox.addButton('Cancel', QDialogButtonBox.RejectRole) self.buttonBox.addButton( 'Apply', QDialogButtonBox.ApplyRole).clicked.connect(self.commit) self.buttonBox.accepted.connect(self.acceptButtonTriggered) self.buttonBox.rejected.connect(self.rejectButtonTriggered) self.layout.addWidget(self.buttonBox) self.setMinimumWidth(self.tab.widget(0).width()) self.setMinimumHeight(self.tab.widget(0).height()) def acceptButtonTriggered(self): self.accept() def rejectButtonTriggered(self): self.reject() def commit(self): for i in range(0, self.tab.count()): self.tab.widget(i).commit() def rollback(self): for i in range(0, self.tab.count()): self.tab.widget(i).rollback()
class UserDefinedDevice(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) self._layout = QVBoxLayout(self) self.setLayout(self._layout) self.log = QPlainTextEdit(self) self._layout.addWidget(self.log) self.log.setPlainText(_('Getting device information') + '...') self.copy = QPushButton(_('Copy to &clipboard')) self.copy.setDefault(True) self.setWindowTitle(_('User-defined device information')) self.setWindowIcon(QIcon(I('debug.png'))) self.copy.clicked.connect(self.copy_to_clipboard) self.ok = QPushButton('&OK') self.ok.setAutoDefault(False) self.ok.clicked.connect(self.accept) self.bbox = QDialogButtonBox(self) self.bbox.addButton(self.copy, QDialogButtonBox.ButtonRole.ActionRole) self.bbox.addButton(self.ok, QDialogButtonBox.ButtonRole.AcceptRole) self._layout.addWidget(self.bbox) self.resize(750, 500) self.bbox.setEnabled(False) QTimer.singleShot(1000, self.device_info) def device_info(self): try: from calibre.devices import device_info r = step_dialog( self.parent(), _('Device Detection'), _('Ensure your device is disconnected, then press OK')) if r: self.close() return before = device_info() r = step_dialog( self.parent(), _('Device Detection'), _('Ensure your device is connected, then press OK')) if r: self.close() return after = device_info() new_devices = after['device_set'] - before['device_set'] res = '' if len(new_devices) == 1: def fmtid(x): x = x or 0 if isinstance(x, numbers.Integral): x = hex(x) if not x.startswith('0x'): x = '0x' + x return x for d in new_devices: res = _('USB Vendor ID (in hex)') + ': ' + \ fmtid(after['device_details'][d][0]) + '\n' res += _('USB Product ID (in hex)') + ': ' + \ fmtid(after['device_details'][d][1]) + '\n' res += _('USB Revision ID (in hex)') + ': ' + \ fmtid(after['device_details'][d][2]) + '\n' trailer = _( 'Copy these values to the clipboard, paste them into an ' 'editor, then enter them into the USER_DEVICE by ' 'customizing the device plugin in Preferences->Advanced->Plugins. ' 'Remember to also enter the folders where you want the books to ' 'be put. You must restart calibre for your changes ' 'to take effect.\n') self.log.setPlainText(res + '\n\n' + trailer) finally: self.bbox.setEnabled(True) def copy_to_clipboard(self): QApplication.clipboard().setText(self.log.toPlainText())
def ask_link(self): class Ask(QDialog): def accept(self): if self.treat_as_image.isChecked(): url = self.url.text() if url.lower().split(':', 1)[0] in ('http', 'https'): error_dialog(self, _('Remote images not supported'), _( 'You must download the image to your computer, URLs pointing' ' to remote images are not supported.'), show=True) return QDialog.accept(self) d = Ask(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(): filetypes = [] if d.treat_as_image.isChecked(): filetypes = [(_('Images'), 'png jpeg jpg gif'.split())] files = choose_files(d, 'select link file', _('Choose file'), filetypes, 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 setup_ui(self): # {{{ self.setWindowModality(Qt.ApplicationModal) self.setWindowIcon(QIcon(I('column.png'))) self.vl = l = QVBoxLayout(self) self.heading_label = la = QLabel('') l.addWidget(la) self.shortcuts = s = QLabel('') s.setWordWrap(True) s.linkActivated.connect(self.shortcut_activated) text = '<p>' + _('Quick create:') for col, name in [('isbn', _('ISBN')), ('formats', _('Formats')), ('yesno', _('Yes/No')), ('tags', _('Tags')), ('series', _('Series')), ('rating', _('Rating')), ('people', _("Names")), ('text', _('Short text'))]: text += ' <a href="col:%s">%s</a>,' % (col, name) text = text[:-1] s.setText(text) l.addWidget(s) self.g = g = QGridLayout() l.addLayout(g) l.addStretch(10) self.button_box = bb = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, self) bb.accepted.connect(self.accept), bb.rejected.connect(self.reject) l.addWidget(bb) def add_row(text, widget): if text is None: f = g.addWidget if isinstance(widget, QWidget) else g.addLayout f(widget, g.rowCount(), 0, 1, -1) return row = g.rowCount() la = QLabel(text) g.addWidget(la, row, 0, 1, 1) if isinstance(widget, QWidget): la.setBuddy(widget) g.addWidget(widget, row, 1, 1, 1) else: widget.setContentsMargins(0, 0, 0, 0) g.addLayout(widget, row, 1, 1, 1) for i in range(widget.count()): w = widget.itemAt(i).widget() if isinstance(w, QWidget): la.setBuddy(w) break return la # Lookup name self.column_name_box = cnb = QLineEdit(self) cnb.setToolTip( _("Used for searching the column. Must contain only digits and lower case letters." )) add_row(_("&Lookup name"), cnb) # Heading self.column_heading_box = chb = QLineEdit(self) chb.setToolTip( _("Column heading in the library view and category name in the Tag browser" )) add_row(_("Column &heading"), chb) # Column Type h = QHBoxLayout() self.column_type_box = ctb = QComboBox(self) ctb.setMinimumWidth(70) ctb.setToolTip( _("What kind of information will be kept in the column.")) h.addWidget(ctb) self.use_decorations = ud = QCheckBox(_("Show &checkmarks"), self) ud.setToolTip( _("Show check marks in the GUI. Values of 'yes', 'checked', and 'true'\n" "will show a green check. Values of 'no', 'unchecked', and 'false' will show a red X.\n" "Everything else will show nothing.")) h.addWidget(ud) self.is_names = ins = QCheckBox(_("Contains names"), self) ins.setToolTip( _("Check this box if this column contains names, like the authors column." )) h.addWidget(ins) add_row(_("&Column type"), h) # Description self.description_box = d = QLineEdit(self) d.setToolTip(_("Optional text describing what this column is for")) add_row(_("D&escription"), d) # Date/number formatting h = QHBoxLayout() self.format_box = fb = QLineEdit(self) h.addWidget(fb) self.format_default_label = la = QLabel('') la.setOpenExternalLinks(True), la.setWordWrap(True) h.addWidget(la) self.format_label = add_row('', h) # Template self.composite_box = cb = QLineEdit(self) self.composite_default_label = cdl = QLabel(_("Default: (nothing)")) cb.setToolTip( _("Field template. Uses the same syntax as save templates.")) cdl.setToolTip( _("Similar to save templates. For example, %s") % "{title} {isbn}") h = QHBoxLayout() h.addWidget(cb), h.addWidget(cdl) self.composite_label = add_row(_("&Template"), h) # Comments properties self.comments_heading_position = ct = QComboBox(self) for k, text in (('hide', _('No heading')), ('above', _('Show heading above the text')), ('side', _('Show heading to the side of the text'))): ct.addItem(text, k) ct.setToolTip( _('Choose whether or not the column heading is shown in the Book\n' 'details panel and, if shown, where')) self.comments_heading_position_label = add_row(_('Column heading'), ct) self.comments_type = ct = QComboBox(self) for k, text in (('html', 'HTML'), ('short-text', _('Short text, like a title')), ('long-text', _('Plain text')), ('markdown', _('Plain text formatted using markdown'))): ct.addItem(text, k) ct.setToolTip( _('Choose how the data in this column is interpreted.\n' 'This controls how the data is displayed in the Book details panel\n' 'and how it is edited.')) self.comments_type_label = add_row( _('Interpret this column as:') + ' ', ct) # Values for enum type l = QGridLayout() self.enum_box = eb = QLineEdit(self) eb.setToolTip( _("A comma-separated list of permitted values. The empty value is always\n" "included, and is the default. For example, the list 'one,two,three' has\n" "four values, the first of them being the empty value.")) self.enum_default_label = la = QLabel(_("Values")) la.setBuddy(eb) l.addWidget(eb), l.addWidget(la, 0, 1) self.enum_colors = ec = QLineEdit(self) ec.setToolTip( _("A list of color names to use when displaying an item. The\n" "list must be empty or contain a color for each value.")) self.enum_colors_label = la = QLabel(_('Colors')) la.setBuddy(ec) l.addWidget(ec), l.addWidget(la, 1, 1) self.enum_label = add_row(_('&Values'), l) # Rating allow half stars self.allow_half_stars = ahs = QCheckBox(_('Allow half stars')) ahs.setToolTip( _('Allow half star ratings, for example: ') + '<span style="font-family:calibre Symbols">★★★½</span>') add_row(None, ahs) # Composite display properties l = QHBoxLayout() self.composite_sort_by_label = la = QLabel(_("&Sort/search column by")) self.composite_sort_by = csb = QComboBox(self) la.setBuddy(csb), csb.setToolTip( _("How this column should handled in the GUI when sorting and searching" )) l.addWidget(la), l.addWidget(csb) self.composite_make_category = cmc = QCheckBox( _("Show in Tag browser")) cmc.setToolTip( _("If checked, this column will appear in the Tag browser as a category" )) l.addWidget(cmc) self.composite_contains_html = cch = QCheckBox( _("Show as HTML in Book details")) cch.setToolTip( '<p>' + _('If checked, this column will be displayed as HTML in ' 'Book details and the Content server. This can be used to ' 'construct links with the template language. For example, ' 'the template ' '<pre><big><b>{title}</b></big>' '{series:| [|}{series_index:| [|]]}</pre>' 'will create a field displaying the title in bold large ' 'characters, along with the series, for example <br>"<big><b>' 'An Oblique Approach</b></big> [Belisarius [1]]". The template ' '<pre><a href="https://www.beam-ebooks.de/ebook/{identifiers' ':select(beam)}">Beam book</a></pre> ' 'will generate a link to the book on the Beam e-books site.') + '</p>') l.addWidget(cch) add_row(None, l) self.resize(self.sizeHint())
class IgnoredFolders(QDialog): def __init__(self, dev, ignored_folders=None, parent=None): QDialog.__init__(self, parent) self.l = l = QVBoxLayout() self.setLayout(l) self.la = la = QLabel('<p>' + _('<b>Scanned folders:</b>') + ' ' + _('You can select which folders calibre will ' 'scan when searching this device for books.')) la.setWordWrap(True) l.addWidget(la) self.tabs = QTabWidget(self) l.addWidget(self.tabs) self.widgets = [] for storage in dev.filesystem_cache.entries: self.dev = dev w = Storage(storage, item_func=self.create_item) del self.dev self.tabs.addTab(w, storage.name) self.widgets.append(w) w.itemChanged.connect(self.item_changed) self.la2 = la = QLabel( _('If you a select a previously unselected folder, any sub-folders' ' will not be visible until you restart calibre.')) l.addWidget(la) la.setWordWrap(True) self.bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.bb.accepted.connect(self.accept) self.bb.rejected.connect(self.reject) self.sab = self.bb.addButton(_('Select &all'), self.bb.ActionRole) self.sab.clicked.connect(self.select_all) self.snb = self.bb.addButton(_('Select &none'), self.bb.ActionRole) self.snb.clicked.connect(self.select_none) l.addWidget(self.bb) self.setWindowTitle(_('Choose folders to scan')) self.setWindowIcon(QIcon(I('devices/tablet.png'))) self.resize(600, 500) def item_changed(self, item, column): w = item.treeWidget() root = w.invisibleRootItem() w.itemChanged.disconnect(self.item_changed) try: if item.checkState(0) == Qt.Checked: # Ensure that the parents of this item are checked p = item.parent() while p is not None and p is not root: p.setCheckState(0, Qt.Checked) p = p.parent() # Set the state of all descendants to the same state as this item for child in self.iterchildren(item): child.setCheckState(0, item.checkState(0)) finally: w.itemChanged.connect(self.item_changed) def iterchildren(self, node): ' Iterate over all descendants of node ' for i in range(node.childCount()): child = node.child(i) yield child for gc in self.iterchildren(child): yield gc def create_item(self, f, parent): name = f.name ans = QTreeWidgetItem(parent, [name]) ans.setData(0, Qt.UserRole, '/'.join(f.full_path[1:])) ans.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) ans.setCheckState( 0, Qt.Unchecked if self.dev.is_folder_ignored( f.storage_id, f.full_path[1:]) else Qt.Checked) ans.setData(0, Qt.DecorationRole, file_icon_provider().icon_from_ext('dir')) return ans def select_all(self): w = self.tabs.currentWidget() for i in range(w.invisibleRootItem().childCount()): c = w.invisibleRootItem().child(i) c.setCheckState(0, Qt.Checked) def select_none(self): w = self.tabs.currentWidget() for i in range(w.invisibleRootItem().childCount()): c = w.invisibleRootItem().child(i) c.setCheckState(0, Qt.Unchecked) @property def ignored_folders(self): ans = {} for w in self.widgets: folders = set() for node in self.iterchildren(w.invisibleRootItem()): if node.checkState(0) == Qt.Checked: continue path = unicode_type(node.data(0, Qt.UserRole) or '') parent = path.rpartition('/')[0] if '/' not in path or icu_lower(parent) not in folders: folders.add(icu_lower(path)) ans[unicode_type(w.storage.storage_id)] = list(folders) return ans
class PluginUpdaterDialog(SizePersistedDialog): initial_extra_size = QSize(350, 100) forum_label_text = _('Plugin homepage') def __init__(self, gui, initial_filter=FILTER_UPDATE_AVAILABLE): SizePersistedDialog.__init__( self, gui, 'Plugin Updater plugin:plugin updater dialog') self.gui = gui self.forum_link = None self.zip_url = None self.model = None self.do_restart = False self._initialize_controls() self._create_context_menu() display_plugins = read_available_plugins() if display_plugins: self.model = DisplayPluginModel(display_plugins) self.proxy_model = DisplayPluginSortFilterModel(self) self.proxy_model.setSourceModel(self.model) self.plugin_view.setModel(self.proxy_model) self.plugin_view.resizeColumnsToContents() self.plugin_view.selectionModel().currentRowChanged.connect( self._plugin_current_changed) self.plugin_view.doubleClicked.connect(self.install_button.click) self.filter_combo.setCurrentIndex(initial_filter) self._select_and_focus_view() else: error_dialog(self.gui, _('Update Check Failed'), _('Unable to reach the plugin index page.'), det_msg=INDEX_URL, show=True) self.filter_combo.setEnabled(False) # Cause our dialog size to be restored from prefs or created on first usage self.resize_dialog() def _initialize_controls(self): self.setWindowTitle(_('User plugins')) self.setWindowIcon(QIcon(I('plugins/plugin_updater.png'))) layout = QVBoxLayout(self) self.setLayout(layout) title_layout = ImageTitleLayout(self, 'plugins/plugin_updater.png', _('User Plugins')) layout.addLayout(title_layout) header_layout = QHBoxLayout() layout.addLayout(header_layout) self.filter_combo = PluginFilterComboBox(self) self.filter_combo.setMinimumContentsLength(20) self.filter_combo.currentIndexChanged[int].connect( self._filter_combo_changed) header_layout.addWidget(QLabel( _('Filter list of plugins') + ':', self)) header_layout.addWidget(self.filter_combo) header_layout.addStretch(10) # filter plugins by name header_layout.addWidget(QLabel(_('Filter by name') + ':', self)) self.filter_by_name_lineedit = QLineEdit(self) self.filter_by_name_lineedit.setText("") self.filter_by_name_lineedit.textChanged.connect( self._filter_name_lineedit_changed) header_layout.addWidget(self.filter_by_name_lineedit) self.plugin_view = QTableView(self) self.plugin_view.horizontalHeader().setStretchLastSection(True) self.plugin_view.setSelectionBehavior(QAbstractItemView.SelectRows) self.plugin_view.setSelectionMode(QAbstractItemView.SingleSelection) self.plugin_view.setAlternatingRowColors(True) self.plugin_view.setSortingEnabled(True) self.plugin_view.setIconSize(QSize(28, 28)) layout.addWidget(self.plugin_view) details_layout = QHBoxLayout() layout.addLayout(details_layout) forum_label = self.forum_label = QLabel('') forum_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard) forum_label.linkActivated.connect(self._forum_label_activated) details_layout.addWidget(QLabel(_('Description') + ':', self), 0, Qt.AlignLeft) details_layout.addWidget(forum_label, 1, Qt.AlignRight) self.description = QLabel(self) self.description.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.description.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.description.setMinimumHeight(40) self.description.setWordWrap(True) layout.addWidget(self.description) self.button_box = QDialogButtonBox(QDialogButtonBox.Close) self.button_box.rejected.connect(self.reject) self.finished.connect(self._finished) self.install_button = self.button_box.addButton( _('&Install'), QDialogButtonBox.AcceptRole) self.install_button.setToolTip(_('Install the selected plugin')) self.install_button.clicked.connect(self._install_clicked) self.install_button.setEnabled(False) self.configure_button = self.button_box.addButton( ' ' + _('&Customize plugin ') + ' ', QDialogButtonBox.ResetRole) self.configure_button.setToolTip( _('Customize the options for this plugin')) self.configure_button.clicked.connect(self._configure_clicked) self.configure_button.setEnabled(False) layout.addWidget(self.button_box) def update_forum_label(self): txt = '' if self.forum_link: txt = '<a href="%s">%s</a>' % (self.forum_link, self.forum_label_text) self.forum_label.setText(txt) def _create_context_menu(self): self.plugin_view.setContextMenuPolicy(Qt.ActionsContextMenu) self.install_action = QAction( QIcon(I('plugins/plugin_upgrade_ok.png')), _('&Install'), self) self.install_action.setToolTip(_('Install the selected plugin')) self.install_action.triggered.connect(self._install_clicked) self.install_action.setEnabled(False) self.plugin_view.addAction(self.install_action) self.history_action = QAction(QIcon(I('chapters.png')), _('Version &History'), self) self.history_action.setToolTip( _('Show history of changes to this plugin')) self.history_action.triggered.connect(self._history_clicked) self.history_action.setEnabled(False) self.plugin_view.addAction(self.history_action) self.forum_action = QAction(QIcon(I('plugins/mobileread.png')), _('Plugin &Forum Thread'), self) self.forum_action.triggered.connect(self._forum_label_activated) self.forum_action.setEnabled(False) self.plugin_view.addAction(self.forum_action) sep1 = QAction(self) sep1.setSeparator(True) self.plugin_view.addAction(sep1) self.toggle_enabled_action = QAction(_('Enable/&Disable plugin'), self) self.toggle_enabled_action.setToolTip( _('Enable or disable this plugin')) self.toggle_enabled_action.triggered.connect( self._toggle_enabled_clicked) self.toggle_enabled_action.setEnabled(False) self.plugin_view.addAction(self.toggle_enabled_action) self.uninstall_action = QAction(_('&Remove plugin'), self) self.uninstall_action.setToolTip(_('Uninstall the selected plugin')) self.uninstall_action.triggered.connect(self._uninstall_clicked) self.uninstall_action.setEnabled(False) self.plugin_view.addAction(self.uninstall_action) sep2 = QAction(self) sep2.setSeparator(True) self.plugin_view.addAction(sep2) self.donate_enabled_action = QAction(QIcon(I('donate.png')), _('Donate to developer'), self) self.donate_enabled_action.setToolTip( _('Donate to the developer of this plugin')) self.donate_enabled_action.triggered.connect(self._donate_clicked) self.donate_enabled_action.setEnabled(False) self.plugin_view.addAction(self.donate_enabled_action) sep3 = QAction(self) sep3.setSeparator(True) self.plugin_view.addAction(sep3) self.configure_action = QAction(QIcon(I('config.png')), _('&Customize plugin'), self) self.configure_action.setToolTip( _('Customize the options for this plugin')) self.configure_action.triggered.connect(self._configure_clicked) self.configure_action.setEnabled(False) self.plugin_view.addAction(self.configure_action) def _finished(self, *args): if self.model: update_plugins = filter(filter_upgradeable_plugins, self.model.display_plugins) self.gui.recalc_update_label(len(update_plugins)) def _plugin_current_changed(self, current, previous): if current.isValid(): actual_idx = self.proxy_model.mapToSource(current) display_plugin = self.model.display_plugins[actual_idx.row()] self.description.setText(display_plugin.description) self.forum_link = display_plugin.forum_link self.zip_url = display_plugin.zip_url self.forum_action.setEnabled(bool(self.forum_link)) self.install_button.setEnabled( display_plugin.is_valid_to_install()) self.install_action.setEnabled(self.install_button.isEnabled()) self.uninstall_action.setEnabled(display_plugin.is_installed()) self.history_action.setEnabled(display_plugin.has_changelog) self.configure_button.setEnabled(display_plugin.is_installed()) self.configure_action.setEnabled(self.configure_button.isEnabled()) self.toggle_enabled_action.setEnabled( display_plugin.is_installed()) self.donate_enabled_action.setEnabled( bool(display_plugin.donation_link)) else: self.description.setText('') self.forum_link = None self.zip_url = None self.forum_action.setEnabled(False) self.install_button.setEnabled(False) self.install_action.setEnabled(False) self.uninstall_action.setEnabled(False) self.history_action.setEnabled(False) self.configure_button.setEnabled(False) self.configure_action.setEnabled(False) self.toggle_enabled_action.setEnabled(False) self.donate_enabled_action.setEnabled(False) self.update_forum_label() def _donate_clicked(self): plugin = self._selected_display_plugin() if plugin and plugin.donation_link: open_url(QUrl(plugin.donation_link)) def _select_and_focus_view(self, change_selection=True): if change_selection and self.plugin_view.model().rowCount() > 0: self.plugin_view.selectRow(0) else: idx = self.plugin_view.selectionModel().currentIndex() self._plugin_current_changed(idx, 0) self.plugin_view.setFocus() def _filter_combo_changed(self, idx): self.filter_by_name_lineedit.setText( "" ) # clear the name filter text when a different group was selected self.proxy_model.set_filter_criteria(idx) if idx == FILTER_NOT_INSTALLED: self.plugin_view.sortByColumn(5, Qt.DescendingOrder) else: self.plugin_view.sortByColumn(0, Qt.AscendingOrder) self._select_and_focus_view() def _filter_name_lineedit_changed(self, text): self.proxy_model.set_filter_text( text) # set the filter text for filterAcceptsRow def _forum_label_activated(self): if self.forum_link: open_url(QUrl(self.forum_link)) def _selected_display_plugin(self): idx = self.plugin_view.selectionModel().currentIndex() actual_idx = self.proxy_model.mapToSource(idx) return self.model.display_plugins[actual_idx.row()] def _uninstall_plugin(self, name_to_remove): if DEBUG: prints('Removing plugin: ', name_to_remove) remove_plugin(name_to_remove) # Make sure that any other plugins that required this plugin # to be uninstalled first have the requirement removed for display_plugin in self.model.display_plugins: # Make sure we update the status and display of the # plugin we just uninstalled if name_to_remove in display_plugin.uninstall_plugins: if DEBUG: prints('Removing uninstall dependency for: ', display_plugin.name) display_plugin.uninstall_plugins.remove(name_to_remove) if display_plugin.name == name_to_remove: if DEBUG: prints('Resetting plugin to uninstalled status: ', display_plugin.name) display_plugin.installed_version = None display_plugin.plugin = None display_plugin.uninstall_plugins = [] if self.proxy_model.filter_criteria not in [ FILTER_INSTALLED, FILTER_UPDATE_AVAILABLE ]: self.model.refresh_plugin(display_plugin) def _uninstall_clicked(self): display_plugin = self._selected_display_plugin() if not question_dialog( self, _('Are you sure?'), '<p>' + _('Are you sure you want to uninstall the <b>%s</b> plugin?') % display_plugin.name, show_copy_button=False): return self._uninstall_plugin(display_plugin.name) if self.proxy_model.filter_criteria in [ FILTER_INSTALLED, FILTER_UPDATE_AVAILABLE ]: self.model.beginResetModel(), self.model.endResetModel() self._select_and_focus_view() else: self._select_and_focus_view(change_selection=False) def _install_clicked(self): display_plugin = self._selected_display_plugin() if not question_dialog( self, _('Install %s') % display_plugin.name, '<p>' + _('Installing plugins is a <b>security risk</b>. ' 'Plugins can contain a virus/malware. ' 'Only install it if you got it from a trusted source.' ' Are you sure you want to proceed?'), show_copy_button=False): return if display_plugin.uninstall_plugins: uninstall_names = list(display_plugin.uninstall_plugins) if DEBUG: prints('Uninstalling plugin: ', ', '.join(uninstall_names)) for name_to_remove in uninstall_names: self._uninstall_plugin(name_to_remove) plugin_zip_url = display_plugin.zip_url if DEBUG: prints('Downloading plugin zip attachment: ', plugin_zip_url) self.gui.status_bar.showMessage( _('Downloading plugin zip attachment: %s') % plugin_zip_url) zip_path = self._download_zip(plugin_zip_url) if DEBUG: prints('Installing plugin: ', zip_path) self.gui.status_bar.showMessage(_('Installing plugin: %s') % zip_path) do_restart = False try: from calibre.customize.ui import config installed_plugins = frozenset(config['plugins']) try: plugin = add_plugin(zip_path) except NameConflict as e: return error_dialog(self.gui, _('Already exists'), unicode(e), show=True) # Check for any toolbars to add to. widget = ConfigWidget(self.gui) widget.gui = self.gui widget.check_for_add_to_toolbars(plugin, previously_installed=plugin.name in installed_plugins) self.gui.status_bar.showMessage( _('Plugin installed: %s') % display_plugin.name) d = info_dialog( self.gui, _('Success'), _('Plugin <b>{0}</b> successfully installed under <b>' ' {1} plugins</b>. You may have to restart calibre ' 'for the plugin to take effect.').format( plugin.name, plugin.type), show_copy_button=False) b = d.bb.addButton(_('Restart calibre now'), d.bb.AcceptRole) b.setIcon(QIcon(I('lt.png'))) d.do_restart = False def rf(): d.do_restart = True b.clicked.connect(rf) d.set_details('') d.exec_() b.clicked.disconnect() do_restart = d.do_restart display_plugin.plugin = plugin # We cannot read the 'actual' version information as the plugin will not be loaded yet display_plugin.installed_version = display_plugin.available_version except: if DEBUG: prints('ERROR occurred while installing plugin: %s' % display_plugin.name) traceback.print_exc() error_dialog( self.gui, _('Install Plugin Failed'), _('A problem occurred while installing this plugin.' ' This plugin will now be uninstalled.' ' Please post the error message in details below into' ' the forum thread for this plugin and restart Calibre.'), det_msg=traceback.format_exc(), show=True) if DEBUG: prints('Due to error now uninstalling plugin: %s' % display_plugin.name) remove_plugin(display_plugin.name) display_plugin.plugin = None display_plugin.uninstall_plugins = [] if self.proxy_model.filter_criteria in [ FILTER_NOT_INSTALLED, FILTER_UPDATE_AVAILABLE ]: self.model.beginResetModel(), self.model.endResetModel() self._select_and_focus_view() else: self.model.refresh_plugin(display_plugin) self._select_and_focus_view(change_selection=False) if do_restart: self.do_restart = True self.accept() def _history_clicked(self): display_plugin = self._selected_display_plugin() text = self._read_version_history_html(display_plugin.forum_link) if text: dlg = VersionHistoryDialog(self, display_plugin.name, text) dlg.exec_() else: return error_dialog( self, _('Version history missing'), _('Unable to find the version history for %s') % display_plugin.name, show=True) def _configure_clicked(self): display_plugin = self._selected_display_plugin() plugin = display_plugin.plugin if not plugin.is_customizable(): return info_dialog(self, _('Plugin not customizable'), _('Plugin: %s does not need customization') % plugin.name, show=True) from calibre.customize import InterfaceActionBase if isinstance(plugin, InterfaceActionBase) and not getattr( plugin, 'actual_iaction_plugin_loaded', False): return error_dialog(self, _('Must restart'), _('You must restart calibre before you can' ' configure the <b>%s</b> plugin') % plugin.name, show=True) plugin.do_user_config(self.parent()) def _toggle_enabled_clicked(self): display_plugin = self._selected_display_plugin() plugin = display_plugin.plugin if not plugin.can_be_disabled: return error_dialog(self, _('Plugin cannot be disabled'), _('The plugin: %s cannot be disabled') % plugin.name, show=True) if is_disabled(plugin): enable_plugin(plugin) else: disable_plugin(plugin) self.model.refresh_plugin(display_plugin) def _read_version_history_html(self, forum_link): br = browser() br.set_handle_gzip(True) try: raw = br.open_novisit(forum_link).read() if not raw: return None except: traceback.print_exc() return None raw = raw.decode('utf-8', errors='replace') root = html.fromstring(raw) spoiler_nodes = root.xpath( '//div[@class="smallfont" and strong="Spoiler"]') for spoiler_node in spoiler_nodes: try: if spoiler_node.getprevious() is None: # This is a spoiler node that has been indented using [INDENT] # Need to go up to parent div, then previous node to get header heading_node = spoiler_node.getparent().getprevious() else: # This is a spoiler node after a BR tag from the heading heading_node = spoiler_node.getprevious().getprevious() if heading_node is None: continue if heading_node.text_content().lower().find( 'version history') != -1: div_node = spoiler_node.xpath('div')[0] text = html.tostring(div_node, method='html', encoding=unicode) return re.sub('<div\s.*?>', '<div>', text) except: if DEBUG: prints('======= MobileRead Parse Error =======') traceback.print_exc() prints(html.tostring(spoiler_node)) return None def _download_zip(self, plugin_zip_url): from calibre.ptempfile import PersistentTemporaryFile br = browser(user_agent='%s %s' % (__appname__, __version__)) raw = br.open_novisit(plugin_zip_url).read() with PersistentTemporaryFile('.zip') as pt: pt.write(raw) return pt.name
def _initialize_controls(self): self.setWindowTitle(_('User plugins')) self.setWindowIcon(QIcon(I('plugins/plugin_updater.png'))) layout = QVBoxLayout(self) self.setLayout(layout) title_layout = ImageTitleLayout(self, 'plugins/plugin_updater.png', _('User Plugins')) layout.addLayout(title_layout) header_layout = QHBoxLayout() layout.addLayout(header_layout) self.filter_combo = PluginFilterComboBox(self) self.filter_combo.setMinimumContentsLength(20) self.filter_combo.currentIndexChanged[int].connect( self._filter_combo_changed) header_layout.addWidget(QLabel( _('Filter list of plugins') + ':', self)) header_layout.addWidget(self.filter_combo) header_layout.addStretch(10) # filter plugins by name header_layout.addWidget(QLabel(_('Filter by name') + ':', self)) self.filter_by_name_lineedit = QLineEdit(self) self.filter_by_name_lineedit.setText("") self.filter_by_name_lineedit.textChanged.connect( self._filter_name_lineedit_changed) header_layout.addWidget(self.filter_by_name_lineedit) self.plugin_view = QTableView(self) self.plugin_view.horizontalHeader().setStretchLastSection(True) self.plugin_view.setSelectionBehavior(QAbstractItemView.SelectRows) self.plugin_view.setSelectionMode(QAbstractItemView.SingleSelection) self.plugin_view.setAlternatingRowColors(True) self.plugin_view.setSortingEnabled(True) self.plugin_view.setIconSize(QSize(28, 28)) layout.addWidget(self.plugin_view) details_layout = QHBoxLayout() layout.addLayout(details_layout) forum_label = self.forum_label = QLabel('') forum_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard) forum_label.linkActivated.connect(self._forum_label_activated) details_layout.addWidget(QLabel(_('Description') + ':', self), 0, Qt.AlignLeft) details_layout.addWidget(forum_label, 1, Qt.AlignRight) self.description = QLabel(self) self.description.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.description.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.description.setMinimumHeight(40) self.description.setWordWrap(True) layout.addWidget(self.description) self.button_box = QDialogButtonBox(QDialogButtonBox.Close) self.button_box.rejected.connect(self.reject) self.finished.connect(self._finished) self.install_button = self.button_box.addButton( _('&Install'), QDialogButtonBox.AcceptRole) self.install_button.setToolTip(_('Install the selected plugin')) self.install_button.clicked.connect(self._install_clicked) self.install_button.setEnabled(False) self.configure_button = self.button_box.addButton( ' ' + _('&Customize plugin ') + ' ', QDialogButtonBox.ResetRole) self.configure_button.setToolTip( _('Customize the options for this plugin')) self.configure_button.clicked.connect(self._configure_clicked) self.configure_button.setEnabled(False) layout.addWidget(self.button_box)
def __init__(self, parent, icon, prefs): self.parent = parent self.prefs = prefs self.icon = icon super(AnnotationsAppearance, self).__init__(parent, 'appearance_dialog') self.setWindowTitle(_('Modify appearance')) self.setWindowIcon(icon) self.l = QVBoxLayout(self) self.setLayout(self.l) # Add a label for description #self.description_label = QLabel(_("Descriptive text here")) #self.l.addWidget(self.description_label) # Add a group box, vertical layout for preview window self.preview_gb = QGroupBox(self) self.preview_gb.setTitle(_("Preview")) self.preview_vl = QVBoxLayout(self.preview_gb) self.l.addWidget(self.preview_gb) self.wv = QWebView() self.wv.setHtml('<p></p>') self.wv.setMinimumHeight(100) self.wv.setMaximumHeight(16777215) self.wv.setGeometry(0, 0, 200, 100) self.wv.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.preview_vl.addWidget(self.wv) # Create a group box, horizontal layout for the table self.css_table_gb = QGroupBox(self) self.css_table_gb.setTitle(_("Annotation elements")) self.elements_hl = QHBoxLayout(self.css_table_gb) self.l.addWidget(self.css_table_gb) # Add the group box to the main layout self.elements_table = AnnotationElementsTable(self, 'annotation_elements_tw') self.elements_hl.addWidget(self.elements_table) self.elements_table.initialize() # Options self.options_gb = QGroupBox(self) self.options_gb.setTitle(_("Options")) self.options_gl = QGridLayout(self.options_gb) self.l.addWidget(self.options_gb) current_row = 0 # <hr/> separator # addWidget(widget, row, col, rowspan, colspan) self.hr_checkbox = QCheckBox(_('Add horizontal rule between annotations')) self.hr_checkbox.stateChanged.connect(self.hr_checkbox_changed) self.hr_checkbox.setCheckState( JSONConfig('plugins/annotations').get('appearance_hr_checkbox', False)) self.options_gl.addWidget(self.hr_checkbox, current_row, 0, 1, 4) current_row += 1 # Timestamp self.timestamp_fmt_label = QLabel(_("Timestamp format:")) self.options_gl.addWidget(self.timestamp_fmt_label, current_row, 0) self.timestamp_fmt_le = QLineEdit( JSONConfig('plugins/annotations').get('appearance_timestamp_format', default_timestamp), parent=self) self.timestamp_fmt_le.textEdited.connect(self.timestamp_fmt_changed) self.timestamp_fmt_le.setFont(self.FONT) self.timestamp_fmt_le.setObjectName('timestamp_fmt_le') self.timestamp_fmt_le.setToolTip(_('Format string for timestamp')) self.timestamp_fmt_le.setMaximumWidth(16777215) self.timestamp_fmt_le.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) self.options_gl.addWidget(self.timestamp_fmt_le, current_row, 1) self.timestamp_fmt_reset_tb = QToolButton(self) self.timestamp_fmt_reset_tb.setToolTip(_("Reset to default")) self.timestamp_fmt_reset_tb.setIcon(QIcon(I('trash.png'))) self.timestamp_fmt_reset_tb.clicked.connect(self.reset_timestamp_to_default) self.options_gl.addWidget(self.timestamp_fmt_reset_tb, current_row, 2) self.timestamp_fmt_help_tb = QToolButton(self) self.timestamp_fmt_help_tb.setToolTip(_("Format string reference")) self.timestamp_fmt_help_tb.setIcon(QIcon(I('help.png'))) self.timestamp_fmt_help_tb.clicked.connect(self.show_help) self.options_gl.addWidget(self.timestamp_fmt_help_tb, current_row, 3) # Button box bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.l.addWidget(bb) # Spacer self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.l.addItem(self.spacerItem) # Sizing sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) self.resize_dialog()
def __init__(self, ids, get_metadata, field_metadata, parent=None, window_title=None, reject_button_tooltip=None, accept_all_tooltip=None, reject_all_tooltip=None, revert_tooltip=None, intro_msg=None, action_button=None, **kwargs): QDialog.__init__(self, parent) self.l = l = QVBoxLayout() self.setLayout(l) self.setWindowIcon(QIcon(I('auto_author_sort.png'))) self.get_metadata = get_metadata self.ids = list(ids) self.total = len(self.ids) self.accepted = OrderedDict() self.rejected_ids = set() self.window_title = window_title or _('Compare metadata') if intro_msg: self.la = la = QLabel(intro_msg) la.setWordWrap(True) l.addWidget(la) self.compare_widget = CompareSingle(field_metadata, parent=parent, revert_tooltip=revert_tooltip, **kwargs) self.sa = sa = QScrollArea() l.addWidget(sa) sa.setWidget(self.compare_widget) sa.setWidgetResizable(True) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Cancel) bb.button(bb.Cancel).setAutoDefault(False) bb.rejected.connect(self.reject) if self.total > 1: self.aarb = b = bb.addButton(_('&Accept all remaining'), bb.YesRole) b.setIcon(QIcon(I('ok.png'))), b.setAutoDefault(False) if accept_all_tooltip: b.setToolTip(accept_all_tooltip) b.clicked.connect(self.accept_all_remaining) self.rarb = b = bb.addButton(_('Re&ject all remaining'), bb.NoRole) b.setIcon(QIcon(I('minus.png'))), b.setAutoDefault(False) if reject_all_tooltip: b.setToolTip(reject_all_tooltip) b.clicked.connect(self.reject_all_remaining) self.sb = b = bb.addButton(_('&Reject'), bb.ActionRole) b.clicked.connect(partial(self.next_item, False)) b.setIcon(QIcon(I('minus.png'))), b.setAutoDefault(False) if reject_button_tooltip: b.setToolTip(reject_button_tooltip) self.next_action = ac = QAction(self) ac.setShortcut(QKeySequence(Qt.ALT | Qt.Key_Right)) self.addAction(ac) if action_button is not None: self.acb = b = bb.addButton(action_button[0], bb.ActionRole) b.setIcon(QIcon(action_button[1])) self.action_button_action = action_button[2] b.clicked.connect(self.action_button_clicked) self.nb = b = bb.addButton( _('&Next') if self.total > 1 else _('&OK'), bb.ActionRole) if self.total > 1: b.setToolTip( _('Move to next [%s]') % self.next_action.shortcut().toString(QKeySequence.NativeText)) self.next_action.triggered.connect(b.click) b.setIcon(QIcon(I('forward.png' if self.total > 1 else 'ok.png'))) b.clicked.connect(partial(self.next_item, True)) b.setDefault(True), b.setAutoDefault(True) self.bbh = h = QHBoxLayout() h.setContentsMargins(0, 0, 0, 0) l.addLayout(h) self.markq = m = QCheckBox(_('&Mark rejected books')) m.setChecked(gprefs['metadata_diff_mark_rejected']) m.stateChanged[int].connect( lambda: gprefs.set('metadata_diff_mark_rejected', m.isChecked())) m.setToolTip( _('Mark rejected books in the book list after this dialog is closed' )) h.addWidget(m), h.addWidget(bb) self.next_item(True) desktop = QApplication.instance().desktop() geom = desktop.availableGeometry(parent or self) width = max(700, min(950, geom.width() - 50)) height = max(650, min(1000, geom.height() - 100)) self.resize(QSize(width, height)) geom = gprefs.get('diff_dialog_geom', None) if geom is not None: self.restoreGeometry(geom) b.setFocus(Qt.OtherFocusReason)
def __init__(self, fm, pref_name, parent=None): QDialog.__init__(self, parent) self.fm = fm if pref_name == 'column_color_rules': self.rule_kind = 'color' rule_text = _('column coloring') elif pref_name == 'column_icon_rules': self.rule_kind = 'icon' rule_text = _('column icon') elif pref_name == 'cover_grid_icon_rules': self.rule_kind = 'emblem' rule_text = _('Cover grid emblem') self.setWindowIcon(QIcon(I('format-fill-color.png'))) self.setWindowTitle(_('Create/edit a {0} rule').format(rule_text)) self.l = l = QGridLayout(self) self.setLayout(l) self.l1 = l1 = QLabel(_('Create a {0} rule by' ' filling in the boxes below').format(rule_text)) l.addWidget(l1, 0, 0, 1, 8) self.f1 = QFrame(self) self.f1.setFrameShape(QFrame.HLine) l.addWidget(self.f1, 1, 0, 1, 8) self.l2 = l2 = QLabel(_('Add the emblem:') if self.rule_kind == 'emblem' else _('Set the')) l.addWidget(l2, 2, 0) if self.rule_kind == 'color': l.addWidget(QLabel(_('color'))) elif self.rule_kind == 'icon': self.kind_box = QComboBox(self) for tt, t in icon_rule_kinds: self.kind_box.addItem(tt, t) l.addWidget(self.kind_box, 2, 1) self.kind_box.setToolTip(textwrap.fill(_( 'If you choose composed icons and multiple rules match, then all the' ' matching icons will be combined, otherwise the icon from the' ' first rule to match will be used.'))) else: pass self.l3 = l3 = QLabel(_('of the column:')) l.addWidget(l3, 2, 2) self.column_box = QComboBox(self) l.addWidget(self.column_box, 2, 3) self.l4 = l4 = QLabel(_('to')) l.addWidget(l4, 2, 4) if self.rule_kind == 'emblem': l3.setVisible(False), self.column_box.setVisible(False), l4.setVisible(False) def create_filename_box(): self.filename_box = f = QComboBox() self.filenamebox_view = v = QListView() v.setIconSize(QSize(32, 32)) self.filename_box.setView(v) self.orig_filenamebox_view = f.view() f.setMinimumContentsLength(20), f.setSizeAdjustPolicy(f.AdjustToMinimumContentsLengthWithIcon) self.populate_icon_filenames() if self.rule_kind == 'color': self.color_box = ColorButton(parent=self) self.color_label = QLabel('Sample text Sample text') self.color_label.setTextFormat(Qt.RichText) l.addWidget(self.color_box, 2, 5) l.addWidget(self.color_label, 2, 6) l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 7) elif self.rule_kind == 'emblem': create_filename_box() self.update_filename_box() self.filename_button = QPushButton(QIcon(I('document_open.png')), _('&Add new image')) l.addWidget(self.filename_box) l.addWidget(self.filename_button, 2, 6) l.addWidget(QLabel(_('(Images should be square-ish)')), 2, 7) l.setColumnStretch(7, 10) else: create_filename_box() vb = QVBoxLayout() self.multiple_icon_cb = QCheckBox(_('Choose &more than one icon')) vb.addWidget(self.multiple_icon_cb) self.update_filename_box() self.multiple_icon_cb.clicked.connect(self.multiple_box_clicked) vb.addWidget(self.filename_box) l.addLayout(vb, 2, 5) self.filename_button = QPushButton(QIcon(I('document_open.png')), _('&Add icon')) l.addWidget(self.filename_button, 2, 6) l.addWidget(QLabel(_('Icons should be square or landscape')), 2, 7) l.setColumnStretch(7, 10) self.l5 = l5 = QLabel( _('Only if the following conditions are all satisfied:')) l.addWidget(l5, 3, 0, 1, 7) self.scroll_area = sa = QScrollArea(self) sa.setMinimumHeight(300) sa.setMinimumWidth(950) sa.setWidgetResizable(True) l.addWidget(sa, 4, 0, 1, 8) self.add_button = b = QPushButton(QIcon(I('plus.png')), _('Add &another condition')) l.addWidget(b, 5, 0, 1, 8) b.clicked.connect(self.add_blank_condition) self.l6 = l6 = QLabel(_('You can disable a condition by' ' blanking all of its boxes')) l.addWidget(l6, 6, 0, 1, 8) self.bb = bb = QDialogButtonBox( QDialogButtonBox.Ok|QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) l.addWidget(bb, 7, 0, 1, 8) if self.rule_kind != 'color': self.remove_button = b = bb.addButton(_('&Remove icon'), bb.ActionRole) b.setIcon(QIcon(I('minus.png'))) b.setMenu(QMenu()) b.setToolTip('<p>' + _('Remove a previously added icon. Note that doing so will cause rules that use it to stop working.')) self.update_remove_button() self.conditions_widget = QWidget(self) sa.setWidget(self.conditions_widget) self.conditions_widget.setLayout(QVBoxLayout()) self.conditions_widget.layout().setAlignment(Qt.AlignTop) self.conditions = [] if self.rule_kind == 'color': for b in (self.column_box, ): b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon) b.setMinimumContentsLength(15) for key in sorted(displayable_columns(fm), key=lambda k: sort_key(fm[k]['name']) if k != color_row_key else 0): if key == color_row_key and self.rule_kind != 'color': continue name = all_columns_string if key == color_row_key else fm[key]['name'] if name: self.column_box.addItem(name, key) self.column_box.setCurrentIndex(0) if self.rule_kind == 'color': self.color_box.color = '#000' self.update_color_label() self.color_box.color_changed.connect(self.update_color_label) else: self.rule_icon_files = [] self.filename_button.clicked.connect(self.filename_button_clicked) self.resize(self.sizeHint())
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 __init__(self, parent=None, initial=None): QDialog.__init__(self, parent) self.setWindowTitle(_('Choose a texture')) self.l = l = QVBoxLayout() self.setLayout(l) self.tdir = texture_dir() self.images = il = QListWidget(self) il.itemDoubleClicked.connect(self.accept, type=Qt.QueuedConnection) il.setIconSize(QSize(256, 256)) il.setViewMode(il.IconMode) il.setFlow(il.LeftToRight) il.setSpacing(20) il.setSelectionMode(il.SingleSelection) il.itemSelectionChanged.connect(self.update_remove_state) l.addWidget(il) self.ad = ad = QLabel( _('The builtin textures come from <a href="http://subtlepatterns.com">subtlepatterns.com</a>.' )) ad.setOpenExternalLinks(True) ad.setWordWrap(True) l.addWidget(ad) self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) b = self.add_button = bb.addButton(_('Add texture'), bb.ActionRole) b.setIcon(QIcon(I('plus.png'))) b.clicked.connect(self.add_texture) b = self.remove_button = bb.addButton(_('Remove texture'), bb.ActionRole) b.setIcon(QIcon(I('minus.png'))) b.clicked.connect(self.remove_texture) l.addWidget(bb) images = [{ 'fname': ':' + os.path.basename(x), 'path': x, 'name': ' '.join( map(string.capitalize, os.path.splitext(os.path.basename(x))[0].split('_'))) } for x in glob.glob(I('textures/*.png'))] + [ { 'fname': os.path.basename(x), 'path': x, 'name': os.path.splitext(os.path.basename(x))[0], } for x in glob.glob(os.path.join(self.tdir, '*')) if x.rpartition('.')[-1].lower() in {'jpeg', 'png', 'jpg'} ] images.sort(key=lambda x: sort_key(x['name'])) map(self.create_item, images) self.update_remove_state() if initial: existing = { unicode(i.data(Qt.UserRole) or ''): i for i in (self.images.item(c) for c in xrange(self.images.count())) } item = existing.get(initial, None) if item is not None: item.setSelected(True) QTimer.singleShot(100, partial(il.scrollToItem, item)) self.resize(QSize(950, 650))