From 3b146a9b5ef9370a26a025dc2e24786bb4e0019c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 18 Oct 2013 22:13:08 +0530 Subject: [PATCH] Nicer dialog when quitting with unsaved changes --- src/calibre/gui2/tweak_book/boss.py | 52 ++++++++++++++++++++++++++--- src/calibre/gui2/tweak_book/ui.py | 1 + 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index 053cea151e..024b2d2b82 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -8,7 +8,9 @@ __copyright__ = '2013, Kovid Goyal ' import tempfile, shutil -from PyQt4.Qt import QObject, QApplication +from PyQt4.Qt import ( + QObject, QApplication, QDialog, QGridLayout, QLabel, QSize, Qt, + QDialogButtonBox, QIcon, QTimer, QPixmap) from calibre.gui2 import error_dialog, choose_files, question_dialog, info_dialog from calibre.ptempfile import PersistentTemporaryDirectory @@ -27,6 +29,7 @@ class Boss(QObject): self.tdir = None self.save_manager = SaveManager(parent) self.save_manager.report_error.connect(self.report_save_error) + self.doing_terminal_save = False def __call__(self, gui): self.gui = gui @@ -144,21 +147,60 @@ class Boss(QObject): QApplication.instance().quit() def confirm_quit(self): + if self.doing_terminal_save: + return False if self.save_manager.has_tasks: if not question_dialog( self.gui, _('Are you sure?'), _( 'The current book is being saved in the background, quitting will abort' ' the save process, are you sure?'), default_yes=False): return False + if self.gui.action_save.isEnabled(): - if not question_dialog( - self.gui, _('Are you sure?'), _( - 'The current book has unsaved changes, you will lose them if you quit,' - ' are you sure?'), default_yes=False): + d = QDialog(self.gui) + d.l = QGridLayout(d) + d.setLayout(d.l) + d.setWindowTitle(_('Unsaved changes')) + d.i = QLabel('') + d.i.setPixmap(QPixmap(I('save.png')).scaledToHeight(64, Qt.SmoothTransformation)) + d.i.setMaximumSize(QSize(d.i.pixmap().width(), 64)) + d.i.setScaledContents(True) + d.l.addWidget(d.i, 0, 0) + d.m = QLabel(_('There are unsaved changes, if you quit without saving, you will lose them.')) + d.m.setWordWrap(True) + d.l.addWidget(d.m, 0, 1) + d.bb = QDialogButtonBox(QDialogButtonBox.Cancel) + d.bb.rejected.connect(d.reject) + d.bb.accepted.connect(d.accept) + d.l.addWidget(d.bb, 1, 0, 1, 2) + d.do_save = None + def endit(x): + d.do_save = x + d.accept() + b = d.bb.addButton(_('&Save and Quit'), QDialogButtonBox.ActionRole) + b.setIcon(QIcon(I('save.png'))) + b.clicked.connect(lambda *args: endit(True)) + b = d.bb.addButton(_('&Quit without saving'), QDialogButtonBox.ActionRole) + b.clicked.connect(lambda *args: endit(False)) + d.resize(d.sizeHint()) + if d.exec_() != d.Accepted or d.do_save is None: + return False + if d.do_save: + self.gui.action_save.trigger() + self.gui.blocking_job.set_msg(_('Saving, please wait...')) + self.gui.blocking_job.start() + self.doing_terminal_save = True + QTimer.singleShot(50, self.check_terminal_save) return False return True + def check_terminal_save(self): + if self.save_manager.has_tasks: + return QTimer.singleShot(50, self.check_terminal_save) + self.shutdown() + QApplication.instance().quit() + def shutdown(self): self.save_state() self.save_manager.shutdown() diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py index d54f55ed8e..2714120d7b 100644 --- a/src/calibre/gui2/tweak_book/ui.py +++ b/src/calibre/gui2/tweak_book/ui.py @@ -59,6 +59,7 @@ class Main(MainWindow): def reg(icon, text, target, sid, keys, description): ac = QAction(QIcon(I(icon)), text, self) + ac.setObjectName('action-' + sid) ac.triggered.connect(target) if isinstance(keys, type('')): keys = (keys,)