File indexing completed on 2024-05-12 15:58:19

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_idle_watcher.h"
0008 
0009 #include <QTimer>
0010 #include "kis_image.h"
0011 #include "kis_signal_auto_connection.h"
0012 #include "kis_signal_compressor.h"
0013 
0014 
0015 struct KisIdleWatcher::Private
0016 {
0017     static const int IDLE_CHECK_COUNT = 4; /* ticks */
0018 
0019     Private(int delay, KisIdleWatcher *q)
0020         : imageModifiedCompressor(delay,
0021                                   KisSignalCompressor::POSTPONE, q),
0022           idleCheckCounter(0)
0023     {
0024         idleCheckTimer.setSingleShot(true);
0025         idleCheckTimer.setInterval(delay);
0026     }
0027 
0028     KisSignalAutoConnectionsStore connectionsStore;
0029     QVector<KisImageWSP> trackedImages;
0030 
0031     KisSignalCompressor imageModifiedCompressor;
0032 
0033     QTimer idleCheckTimer;
0034     int idleCheckCounter;
0035 };
0036 
0037 KisIdleWatcher::KisIdleWatcher(int delay, QObject *parent)
0038     : QObject(parent), m_d(new Private(delay, this))
0039 {
0040     connect(&m_d->imageModifiedCompressor, SIGNAL(timeout()), SLOT(startIdleCheck()));
0041     connect(&m_d->idleCheckTimer, SIGNAL(timeout()), SLOT(slotIdleCheckTick()));
0042 }
0043 
0044 KisIdleWatcher::~KisIdleWatcher()
0045 {
0046 }
0047 
0048 bool KisIdleWatcher::isIdle() const
0049 {
0050     bool idle = true;
0051 
0052     Q_FOREACH (KisImageSP image, m_d->trackedImages) {
0053         if (!image) continue;
0054 
0055         if (!image->isIdle()) {
0056             idle = false;
0057             break;
0058         }
0059     }
0060 
0061     return idle;
0062 }
0063 
0064 void KisIdleWatcher::setTrackedImages(const QVector<KisImageSP> &images)
0065 {
0066     m_d->connectionsStore.clear();
0067     m_d->trackedImages.clear();
0068 
0069     Q_FOREACH (KisImageSP image, images) {
0070         if (image) {
0071             m_d->trackedImages << image;
0072             m_d->connectionsStore.addConnection(image, SIGNAL(sigImageModified()),
0073                                                 this, SLOT(slotImageModified()));
0074 
0075             m_d->connectionsStore.addConnection(image, SIGNAL(sigIsolatedModeChanged()),
0076                                                 this, SLOT(slotImageModified()));
0077         }
0078     }
0079 }
0080 
0081 void KisIdleWatcher::setTrackedImage(KisImageSP image)
0082 {
0083     QVector<KisImageSP> images;
0084     images << image;
0085     setTrackedImages(images);
0086 }
0087 
0088 void KisIdleWatcher::slotImageModified()
0089 {
0090     stopIdleCheck();
0091     m_d->imageModifiedCompressor.start();
0092 }
0093 
0094 void KisIdleWatcher::startIdleCheck()
0095 {
0096     m_d->idleCheckCounter = 0;
0097     m_d->idleCheckTimer.start();
0098 }
0099 
0100 void KisIdleWatcher::stopIdleCheck()
0101 {
0102     m_d->idleCheckTimer.stop();
0103     m_d->idleCheckCounter = 0;
0104 }
0105 
0106 void KisIdleWatcher::slotIdleCheckTick()
0107 {
0108     if (isIdle()) {
0109         if (m_d->idleCheckCounter >= Private::IDLE_CHECK_COUNT) {
0110             stopIdleCheck();
0111             if (!m_d->trackedImages.isEmpty()) {
0112                 emit startedIdleMode();
0113             }
0114         } else {
0115             m_d->idleCheckCounter++;
0116             m_d->idleCheckTimer.start();
0117         }
0118     } else {
0119         slotImageModified();
0120     }
0121 }