1 | /* |
2 | Copyright (C) 2014 by Elvis Angelaccio <elvis.angelaccio@kdemail.net> |
3 | |
4 | This file is part of Kronometer. |
5 | |
6 | Kronometer is free software: you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation, either version 2 of the License, or |
9 | (at your option) any later version. |
10 | |
11 | Kronometer is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with Kronometer. If not, see <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | #ifndef STOPWATCH_H |
21 | #define STOPWATCH_H |
22 | |
23 | #include <QObject> |
24 | #include <QTime> |
25 | #include <QElapsedTimer> |
26 | |
27 | class QTimerEvent; |
28 | class QDataStream; |
29 | class QDomElement; |
30 | |
31 | /** |
32 | * @brief A Stopwatch class written in Qt. |
33 | * Stopwatch is a simple QObject implementing a real stopwatch. |
34 | * The class provides public slots for start/pause/reset the timer. |
35 | * A slot for lap recording exists too, but the computing of lap times is not a task of this class: |
36 | * Stopwatch simply emits a signal, that the receiver can use to compute lap times. |
37 | */ |
38 | class Stopwatch : public QObject |
39 | { |
40 | Q_OBJECT |
41 | |
42 | public: |
43 | |
44 | enum Granularity |
45 | { |
46 | MILLISECONDS = 1, /**< Stopwatch refreshed every msec. */ |
47 | HUNDREDTHS = 10, /**< Stopwatch refreshed every 10 msec. */ |
48 | TENTHS = 100, /**< Stopwatch refreshed every 100 msec. */ |
49 | SECONDS = 1000 /**< Stopwatch refreshed every sec. */ |
50 | }; |
51 | |
52 | explicit Stopwatch(QObject *parent = nullptr); |
53 | |
54 | /** |
55 | * Set the stopwatch refresh granularity |
56 | * @param g The granularity to be set. |
57 | */ |
58 | void setGranularity(Granularity g); |
59 | |
60 | /** |
61 | * Check if the stopwatch is running |
62 | * @return true if running, false otherwise |
63 | */ |
64 | bool isRunning() const; |
65 | |
66 | /** |
67 | * Check if the stopwatch is paused |
68 | * @return true if paused, false otherwise |
69 | */ |
70 | bool isPaused() const; |
71 | |
72 | /** |
73 | * Check if the stopwatch is inactive |
74 | * @return true if inactive, false otherwise |
75 | */ |
76 | bool isInactive() const; |
77 | |
78 | /** |
79 | * Serialize the stopwatch on the given output stream. |
80 | * Only a paused stopwatch is meant to be serialized. |
81 | * @param out The serialization output stream |
82 | * @return true if the serialization succeeds (i.e. the stopwatch is paused), false otherwise |
83 | */ |
84 | bool serialize(QDataStream& out); |
85 | |
86 | /** |
87 | * De-serialize the stopwatch from the given input stream. |
88 | * Only an inactive stopwatch is meant to be serialized. |
89 | * @param in The serialization input stream |
90 | * @return true if the deserialization succeeds (i.e. the stopwatch is inactive), false otherwise |
91 | */ |
92 | bool deserialize(QDataStream& in); |
93 | |
94 | /** |
95 | * Serialize the stopwatch on the given XML DOM element. |
96 | * The serialization is implemented by adding an attribute (with the given name) to the element. |
97 | * Only a paused stopwatch is meant to be serialized. |
98 | * @param element The XML DOM element to be used as serialization output. |
99 | * @param attributeName The name of the attribute to be added to the element. |
100 | * @return true if the serialization succeeds (i.e. the stopwatch is paused), false otherwise |
101 | */ |
102 | bool serialize(QDomElement& element, const QString& attributeName); |
103 | |
104 | /** |
105 | * De-serialize the stopwatch from the given XML DOM element. |
106 | * The deserialization is implemented by reading an attribute (with the given name) from the element. |
107 | * Only an inactive stopwatch is meant to be serialized. |
108 | * @param element The XML DOM element to be used as serialization input. |
109 | * @param attributeName The name of the attribute to be read. |
110 | * @return true if the deserialization succeeds (i.e. the stopwatch is inactive and the attribute is valid), false otherwise |
111 | */ |
112 | bool deserialize(QDomElement& element, const QString& attributeName); |
113 | |
114 | public slots: |
115 | |
116 | /** |
117 | * Start the stopwatch, if inactive or paused. |
118 | */ |
119 | void onStart(); |
120 | |
121 | /** |
122 | * Pause the stopwatch, if running. |
123 | */ |
124 | void onPause(); |
125 | |
126 | /** |
127 | * Reset the stopwatch to the inactive state. |
128 | */ |
129 | void onReset(); |
130 | |
131 | /** |
132 | * Tells the stopwatch to emits a signal with the last lap time. |
133 | */ |
134 | void onLap(); |
135 | |
136 | signals: |
137 | |
138 | /** |
139 | * Emits a signal with the last lap *absolute* time. |
140 | * This class does not compute *relatives* lap times. |
141 | * You can compute them simply by the difference between consecutives absolute times. |
142 | * @param lapTime The absolute time of the last lap. |
143 | */ |
144 | void lap(const QTime& lapTime); |
145 | |
146 | /** |
147 | * Emits a signal with the current stopwatch time. |
148 | * @param t Current stopwatch time. |
149 | */ |
150 | void time(const QTime& t); |
151 | |
152 | protected: |
153 | |
154 | void timerEvent(QTimerEvent *event); |
155 | |
156 | private: |
157 | |
158 | enum class State |
159 | { |
160 | INACTIVE, /**< Inactive stopwatch. */ |
161 | RUNNING, /**< Running stopwatch. */ |
162 | PAUSED /**< Paused stopwatch. */ |
163 | }; |
164 | |
165 | static const int INACTIVE_TIMER_ID = -1; /** Used for timerId initialization */ |
166 | |
167 | int timerId; /** ID for the QObject timer */ |
168 | qint64 accumulator; /** milliseconds internal counter */ |
169 | State state; /** Stopwatch current state */ |
170 | Granularity granularity; /** Stopwatch current granularity */ |
171 | |
172 | const QTime zero; /** Empty time to be used to add elapsed milliseconds */ |
173 | QElapsedTimer elapsedTimer; /** Stopwatch core class*/ |
174 | }; |
175 | |
176 | |
177 | |
178 | #endif |
179 | |