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 }