File indexing completed on 2024-05-12 15:58:11
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_busy_progress_indicator.h" 0008 0009 #include <QTimer> 0010 #include <QAtomicInt> 0011 0012 #include "KoProgressProxy.h" 0013 0014 0015 struct KisBusyProgressIndicator::Private 0016 { 0017 Private(KisBusyProgressIndicator *_q) 0018 : timer(new QTimer(_q)) 0019 {} 0020 0021 QTimer *timer {nullptr}; // owned by QObject hierarchy 0022 int numEmptyTicks {0}; 0023 QAtomicInt numUpdates; 0024 QAtomicInt timerStarted; 0025 KoProgressProxy *progressProxy {nullptr}; 0026 0027 bool isStarted {false}; 0028 0029 void startProgressReport() 0030 { 0031 if (!progressProxy) { 0032 return; 0033 } 0034 isStarted = true; 0035 progressProxy->setRange(0, 0); 0036 } 0037 0038 void stopProgressReport() 0039 { 0040 if (!isStarted || !progressProxy) { 0041 return; 0042 } 0043 progressProxy->setRange(0, 100); 0044 progressProxy->setValue(100); 0045 isStarted = false; 0046 } 0047 }; 0048 0049 0050 KisBusyProgressIndicator::KisBusyProgressIndicator(KoProgressProxy *progressProxy) 0051 : m_d(new Private(this)) 0052 { 0053 connect(m_d->timer, SIGNAL(timeout()), SLOT(timerFinished())); 0054 connect(this, SIGNAL(sigStartTimer()), SLOT(slotStartTimer())); 0055 m_d->timer->setInterval(200); 0056 m_d->progressProxy = progressProxy; 0057 } 0058 0059 KisBusyProgressIndicator::~KisBusyProgressIndicator() 0060 { 0061 m_d->stopProgressReport(); 0062 } 0063 0064 void KisBusyProgressIndicator::prepareDestroying() 0065 { 0066 m_d->progressProxy = 0; 0067 } 0068 0069 void KisBusyProgressIndicator::timerFinished() 0070 { 0071 int value = m_d->numUpdates.fetchAndStoreOrdered(0); 0072 0073 if (!value) { 0074 m_d->numEmptyTicks++; 0075 0076 if (m_d->numEmptyTicks > 2) { 0077 m_d->timerStarted = 0; 0078 m_d->timer->stop(); 0079 m_d->stopProgressReport(); 0080 } 0081 } else { 0082 m_d->numEmptyTicks = 0; 0083 } 0084 } 0085 0086 void KisBusyProgressIndicator::update() 0087 { 0088 m_d->numUpdates.ref(); 0089 0090 if (!m_d->timerStarted) { 0091 emit sigStartTimer(); 0092 } 0093 } 0094 0095 void KisBusyProgressIndicator::slotStartTimer() 0096 { 0097 m_d->timerStarted.ref(); 0098 m_d->timer->start(); 0099 m_d->startProgressReport(); 0100 }