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 }