mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
When errors occur in lots of background jobs, add an option to the error message to temporarily suppress subsequent error messages. Fixes #886904 ("Error:" boxes during conversion)
This commit is contained in:
parent
ffdbd911e0
commit
bd11311242
@ -9,7 +9,7 @@ import sys
|
|||||||
|
|
||||||
from PyQt4.Qt import (QDialog, QIcon, QApplication, QSize, QKeySequence,
|
from PyQt4.Qt import (QDialog, QIcon, QApplication, QSize, QKeySequence,
|
||||||
QAction, Qt, QTextBrowser, QDialogButtonBox, QVBoxLayout, QGridLayout,
|
QAction, Qt, QTextBrowser, QDialogButtonBox, QVBoxLayout, QGridLayout,
|
||||||
QLabel, QPlainTextEdit, QTextDocument)
|
QLabel, QPlainTextEdit, QTextDocument, QCheckBox, pyqtSignal)
|
||||||
|
|
||||||
from calibre.constants import __version__, isfrozen
|
from calibre.constants import __version__, isfrozen
|
||||||
from calibre.gui2.dialogs.message_box_ui import Ui_Dialog
|
from calibre.gui2.dialogs.message_box_ui import Ui_Dialog
|
||||||
@ -270,12 +270,14 @@ class ErrorNotification(MessageBox): # {{{
|
|||||||
class JobError(QDialog): # {{{
|
class JobError(QDialog): # {{{
|
||||||
|
|
||||||
WIDTH = 600
|
WIDTH = 600
|
||||||
|
do_pop = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, gui):
|
def __init__(self, gui):
|
||||||
QDialog.__init__(self, gui)
|
QDialog.__init__(self, gui)
|
||||||
self.setAttribute(Qt.WA_DeleteOnClose, False)
|
self.setAttribute(Qt.WA_DeleteOnClose, False)
|
||||||
self.gui = gui
|
self.gui = gui
|
||||||
self.queue = []
|
self.queue = []
|
||||||
|
self.do_pop.connect(self.pop, type=Qt.QueuedConnection)
|
||||||
|
|
||||||
self._layout = l = QGridLayout()
|
self._layout = l = QGridLayout()
|
||||||
self.setLayout(l)
|
self.setLayout(l)
|
||||||
@ -285,6 +287,7 @@ class JobError(QDialog): # {{{
|
|||||||
self.icon_label.setPixmap(self.icon.pixmap(128, 128))
|
self.icon_label.setPixmap(self.icon.pixmap(128, 128))
|
||||||
self.icon_label.setMaximumSize(QSize(128, 128))
|
self.icon_label.setMaximumSize(QSize(128, 128))
|
||||||
self.msg_label = QLabel('<p> ')
|
self.msg_label = QLabel('<p> ')
|
||||||
|
self.msg_label.setStyleSheet('QLabel { margin-top: 1ex; }')
|
||||||
self.msg_label.setWordWrap(True)
|
self.msg_label.setWordWrap(True)
|
||||||
self.msg_label.setTextFormat(Qt.RichText)
|
self.msg_label.setTextFormat(Qt.RichText)
|
||||||
self.det_msg = QPlainTextEdit(self)
|
self.det_msg = QPlainTextEdit(self)
|
||||||
@ -302,17 +305,25 @@ class JobError(QDialog): # {{{
|
|||||||
self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
|
self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
|
||||||
self.det_msg_toggle.setToolTip(
|
self.det_msg_toggle.setToolTip(
|
||||||
_('Show detailed information about this error'))
|
_('Show detailed information about this error'))
|
||||||
|
self.suppress = QCheckBox(self)
|
||||||
|
self.suppress.setVisible(False)
|
||||||
|
|
||||||
l.addWidget(self.icon_label, 0, 0, 1, 1)
|
l.addWidget(self.icon_label, 0, 0, 1, 1)
|
||||||
l.addWidget(self.msg_label, 0, 1, 1, 1, Qt.AlignLeft|Qt.AlignTop)
|
l.addWidget(self.msg_label, 0, 1, 1, 1, Qt.AlignTop)
|
||||||
l.addWidget(self.det_msg, 1, 0, 1, 2)
|
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, 2, 0, 1, 2, Qt.AlignRight|Qt.AlignBottom)
|
l.addWidget(self.bb, 3, 0, 1, 2, Qt.AlignRight|Qt.AlignBottom)
|
||||||
|
l.setColumnStretch(1, 100)
|
||||||
|
|
||||||
self.setModal(False)
|
self.setModal(False)
|
||||||
self.base_height = max(200, self.sizeHint().height() + 20)
|
self.base_height = max(200, self.sizeHint().height() + 20)
|
||||||
self.do_resize()
|
self.do_resize()
|
||||||
|
|
||||||
|
def update_suppress_state(self):
|
||||||
|
self.suppress.setText(_(
|
||||||
|
'Hide the remaining %d error messages'%len(self.queue)))
|
||||||
|
self.suppress.setVisible(len(self.queue) > 3)
|
||||||
|
|
||||||
def copy_to_clipboard(self, *args):
|
def copy_to_clipboard(self, *args):
|
||||||
d = QTextDocument()
|
d = QTextDocument()
|
||||||
d.setHtml(self.msg_label.text())
|
d.setHtml(self.msg_label.text())
|
||||||
@ -342,6 +353,33 @@ class JobError(QDialog): # {{{
|
|||||||
self.bb.button(self.bb.Close).setFocus(Qt.OtherFocusReason)
|
self.bb.button(self.bb.Close).setFocus(Qt.OtherFocusReason)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def show_error(self, title, msg, det_msg=u''):
|
||||||
|
self.queue.append((title, msg, det_msg))
|
||||||
|
self.update_suppress_state()
|
||||||
|
self.pop()
|
||||||
|
|
||||||
|
def pop(self):
|
||||||
|
if not self.queue or self.isVisible(): return
|
||||||
|
title, msg, det_msg = self.queue.pop(0)
|
||||||
|
self.setWindowTitle(title)
|
||||||
|
self.msg_label.setText(msg)
|
||||||
|
self.det_msg.setPlainText(det_msg)
|
||||||
|
self.det_msg.setVisible(False)
|
||||||
|
self.det_msg_toggle.setText(self.show_det_msg)
|
||||||
|
self.det_msg_toggle.setVisible(True)
|
||||||
|
self.suppress.setChecked(False)
|
||||||
|
self.update_suppress_state()
|
||||||
|
if not det_msg:
|
||||||
|
self.det_msg_toggle.setVisible(False)
|
||||||
|
self.do_resize()
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
def done(self, r):
|
||||||
|
if self.suppress.isChecked():
|
||||||
|
self.queue = []
|
||||||
|
self.do_pop.emit()
|
||||||
|
return QDialog.done(self, r)
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
@ -349,7 +387,7 @@ if __name__ == '__main__':
|
|||||||
from calibre.gui2.preferences import init_gui
|
from calibre.gui2.preferences import init_gui
|
||||||
gui = init_gui()
|
gui = init_gui()
|
||||||
d = JobError(gui)
|
d = JobError(gui)
|
||||||
d.show()
|
d.show_error('test title', 'some long meaningless test message')
|
||||||
app.exec_()
|
app.exec_()
|
||||||
gui.shutdown()
|
gui.shutdown()
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ from calibre.gui2.keyboard import Manager
|
|||||||
from calibre.gui2.auto_add import AutoAdder
|
from calibre.gui2.auto_add import AutoAdder
|
||||||
from calibre.library.sqlite import sqlite, DatabaseException
|
from calibre.library.sqlite import sqlite, DatabaseException
|
||||||
from calibre.gui2.proceed import ProceedQuestion
|
from calibre.gui2.proceed import ProceedQuestion
|
||||||
|
from calibre.gui2.dialogs.message_box import JobError
|
||||||
|
|
||||||
class Listener(Thread): # {{{
|
class Listener(Thread): # {{{
|
||||||
|
|
||||||
@ -111,6 +112,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
self.proceed_requested.connect(self.do_proceed,
|
self.proceed_requested.connect(self.do_proceed,
|
||||||
type=Qt.QueuedConnection)
|
type=Qt.QueuedConnection)
|
||||||
self.proceed_question = ProceedQuestion(self)
|
self.proceed_question = ProceedQuestion(self)
|
||||||
|
self.job_error_dialog = JobError(self)
|
||||||
self.keyboard = Manager(self)
|
self.keyboard = Manager(self)
|
||||||
_gui = self
|
_gui = self
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
@ -690,12 +692,9 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if not minz:
|
if not minz:
|
||||||
d = error_dialog(self, dialog_title,
|
self.job_error_dialog.show_error(dialog_title,
|
||||||
_('<b>Failed</b>')+': '+unicode(job.description),
|
_('<b>Failed</b>')+': '+unicode(job.description),
|
||||||
det_msg=job.details)
|
det_msg=job.details)
|
||||||
d.setModal(False)
|
|
||||||
d.show()
|
|
||||||
self._modeless_dialogs.append(d)
|
|
||||||
|
|
||||||
def read_settings(self):
|
def read_settings(self):
|
||||||
geometry = config['main_window_geometry']
|
geometry = config['main_window_geometry']
|
||||||
|
Loading…
x
Reference in New Issue
Block a user