File indexing completed on 2025-01-26 04:08:03
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_delayed_save_dialog.h" 0008 #include "ui_kis_delayed_save_dialog.h" 0009 0010 #include <QElapsedTimer> 0011 #include <QThread> 0012 #include <QTimer> 0013 #include <QtGlobal> 0014 0015 #include "kis_debug.h" 0016 #include "kis_image.h" 0017 #include "kis_composite_progress_proxy.h" 0018 0019 struct Q_DECL_HIDDEN KisDelayedSaveDialog::Private { 0020 Private(KisImageSP _image, int _busyWait, Type _type) : image(_image), busyWait(_busyWait), type(_type) {} 0021 0022 KisImageSP image; 0023 QTimer updateTimer; 0024 int busyWait; 0025 0026 bool checkImageIdle() { 0027 const bool allowLocked = type != SaveDialog; 0028 return image->isIdle(allowLocked); 0029 } 0030 0031 Type type; 0032 }; 0033 0034 class Q_DECL_HIDDEN WdgDelayedSaveDialog : public QWidget, public Ui::KisDelayedSaveDialog 0035 { 0036 Q_OBJECT 0037 0038 public: 0039 WdgDelayedSaveDialog(QWidget *parent = nullptr) 0040 : QWidget(parent) 0041 { 0042 setupUi(this); 0043 } 0044 }; 0045 0046 KisDelayedSaveDialog::KisDelayedSaveDialog(KisImageSP image, Type type, int busyWait, QWidget *parent) 0047 : KoDialog(parent) 0048 , ui(new WdgDelayedSaveDialog()) 0049 , m_d(new Private(image, busyWait, type)) 0050 { 0051 KIS_ASSERT_RECOVER_NOOP(image); 0052 0053 setMainWidget(ui); 0054 0055 if (type == SaveDialog) { 0056 setButtons(KoDialog::Ok | KoDialog::Cancel | KoDialog::User1); 0057 setButtonText(KoDialog::Ok, i18n("Save without waiting")); 0058 setButtonText(KoDialog::Cancel, i18n("Cancel operation and save")); 0059 setButtonText(KoDialog::User1, i18n("Close, do not save")); 0060 0061 connect(this, &KoDialog::okClicked, this, &KisDelayedSaveDialog::slotIgnoreRequested); 0062 0063 connect(this, &KoDialog::cancelClicked, this, &KisDelayedSaveDialog::slotCancelRequested); 0064 0065 connect(this, &KoDialog::user1Clicked, this, &KisDelayedSaveDialog::reject); 0066 } else if (type == GeneralDialog) { 0067 setButtons(KoDialog::Cancel); 0068 connect(this, &KoDialog::cancelClicked, &KisDelayedSaveDialog::reject); 0069 } else { // type == ForcedDialog, disable closing 0070 setButtons(KoDialog::None); 0071 setWindowFlags(windowFlags() & ~Qt::WindowCloseButtonHint); 0072 } 0073 0074 connect(&m_d->updateTimer, &QTimer::timeout, this, &KisDelayedSaveDialog::slotTimerTimeout); 0075 0076 m_d->image->compositeProgressProxy()->addProxy(ui->progressBar); 0077 0078 resize(sizeHint()); 0079 } 0080 0081 KisDelayedSaveDialog::~KisDelayedSaveDialog() 0082 { 0083 m_d->image->compositeProgressProxy()->removeProxy(ui->progressBar); 0084 delete ui; 0085 } 0086 0087 void KisDelayedSaveDialog::blockIfImageIsBusy() 0088 { 0089 if (m_d->checkImageIdle()) { 0090 setResult(Accepted); 0091 return; 0092 } 0093 0094 m_d->image->requestStrokeEnd(); 0095 0096 QElapsedTimer t; 0097 t.start(); 0098 0099 while (t.elapsed() < m_d->busyWait) { 0100 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); 0101 0102 if (m_d->checkImageIdle()) { 0103 setResult(Accepted); 0104 return; 0105 } 0106 0107 QThread::yieldCurrentThread(); 0108 } 0109 0110 m_d->updateTimer.start(200); 0111 exec(); 0112 m_d->updateTimer.stop(); 0113 } 0114 0115 void KisDelayedSaveDialog::slotTimerTimeout() 0116 { 0117 if (m_d->checkImageIdle()) { 0118 accept(); 0119 } 0120 } 0121 0122 void KisDelayedSaveDialog::slotCancelRequested() 0123 { 0124 m_d->image->requestStrokeCancellation(); 0125 } 0126 0127 void KisDelayedSaveDialog::slotIgnoreRequested() 0128 { 0129 done(Ignored); 0130 } 0131 0132 #include "kis_delayed_save_dialog.moc"