File indexing completed on 2024-05-19 16:51:55

0001 /*
0002     Copyright (C) 2014 by Elvis Angelaccio <elvis.angelaccio@kde.org>
0003 
0004     This file is part of Kronometer.
0005 
0006     Kronometer is free software: you can redistribute it and/or modify
0007     it under the terms of the GNU General Public License as published by
0008     the Free Software Foundation, either version 2 of the License, or
0009     (at your option) any later version.
0010 
0011     Kronometer is distributed in the hope that it will be useful,
0012     but WITHOUT ANY WARRANTY; without even the implied warranty of
0013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014     GNU General Public License for more details.
0015 
0016     You should have received a copy of the GNU General Public License
0017     along with Kronometer.  If not, see <http://www.gnu.org/licenses/>.
0018 */
0019 
0020 #include "stopwatch.h"
0021 
0022 #include <QCoreApplication>
0023 #include <QTimerEvent>
0024 
0025 Stopwatch::Stopwatch(QObject *parent) : QObject(parent) {}
0026 
0027 void Stopwatch::setGranularity(Granularity g)
0028 {
0029     m_granularity = g;
0030 
0031     // whenever granularity is changed, also apply that granularity to the timer event
0032     if (m_timerId != INACTIVE_TIMER_ID) {
0033         killTimer(m_timerId);
0034         m_timerId = startTimer(granularity());
0035     }
0036 }
0037 
0038 bool Stopwatch::isRunning() const
0039 {
0040     return m_state == State::Running;
0041 }
0042 
0043 bool Stopwatch::isPaused() const
0044 {
0045     return m_state == State::Paused;
0046 }
0047 
0048 bool Stopwatch::isInactive() const
0049 {
0050     return m_state == State::Inactive;
0051 }
0052 
0053 int Stopwatch::raw() const
0054 {
0055     return m_accumulator;
0056 }
0057 
0058 bool Stopwatch::initialize(int rawData)
0059 {
0060     if (not isInactive() or rawData <= 0) {
0061         return false;
0062     }
0063 
0064     m_accumulator = rawData;
0065     m_state = State::Paused;
0066     emit time(m_accumulator);  // it signals that has been deserialized and can be resumed
0067 
0068     return true;
0069 }
0070 
0071 void Stopwatch::start()
0072 {
0073     if (isInactive()) {
0074         m_accumulator = 0;
0075         m_elapsedTimer.start();
0076 
0077         if (m_timerId == INACTIVE_TIMER_ID) {
0078             m_timerId = startTimer(granularity());
0079         }
0080     }
0081     else if (isPaused()) {
0082         m_elapsedTimer.restart();
0083         m_timerId = startTimer(granularity());
0084     }
0085 
0086     m_state = State::Running;
0087     emit running();
0088 }
0089 
0090 void Stopwatch::pause()
0091 {
0092     if (m_elapsedTimer.isValid()) {
0093         m_accumulator += m_elapsedTimer.elapsed();
0094     }
0095 
0096     m_elapsedTimer.invalidate();
0097     m_state = State::Paused;
0098     emit paused();
0099 }
0100 
0101 void Stopwatch::reset()
0102 {
0103     m_elapsedTimer.invalidate();          // if state is running, it will emit a zero time at next timerEvent() call
0104     QCoreApplication::processEvents();
0105     emit time(0);
0106     m_state = State::Inactive;
0107     emit inactive();
0108 }
0109 
0110 void Stopwatch::storeLap()
0111 {
0112     auto lapTime = m_accumulator;
0113 
0114     if (m_elapsedTimer.isValid()) {
0115         lapTime += m_elapsedTimer.elapsed();
0116     }
0117 
0118     const auto zero = QTime {0, 0};
0119     emit lap(zero.addMSecs(lapTime));
0120 }
0121 
0122 void Stopwatch::timerEvent(QTimerEvent *event)
0123 {
0124     if (event->timerId() != m_timerId) {      // forward undesired events
0125         QObject::timerEvent(event);
0126         return;
0127     }
0128 
0129     if (m_elapsedTimer.isValid()) {
0130         emit time(m_accumulator + m_elapsedTimer.elapsed());
0131     }
0132     else {
0133         killTimer(m_timerId);
0134         m_timerId = INACTIVE_TIMER_ID;
0135     }
0136 }
0137 
0138 int Stopwatch::granularity() const
0139 {
0140     return static_cast<int>(m_granularity);
0141 }