1 /*
2    Copyright (C) 2005-2006,2008-2010 Tom Albers <toma@kde.org>
3    Copyright (C) 2005-2006 Bram Schoenmakers <bramschoenmakers@kde.nl>
4    Copyright (C) 2010 Juan Luis Baptiste <juan.baptiste@gmail.com>
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public
8    License as published by the Free Software Foundation; either
9    version 2 of the License, or (at your option) any later version.
10 
11    This program 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 GNU
14    General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 */
21 
22 #ifndef RSITimer_H
23 #define RSITimer_H
24 
25 #include <QThread>
26 #include <QVector>
27 #include <memory>
28 
29 #include "rsitimercounter.h"
30 #include "rsiidletime.h"
31 
32 /**
33  * @class RSITimer
34  * This class controls the timings and arranges the maximizing
35  * and minimizing of the widget.
36  * @author Tom Albers <toma.org>
37  */
38 class RSITimer : public QThread
39 {
40     Q_OBJECT
41     friend class RSITimerTest;
42 
43 public:
44     /**
45      * Constructor
46      * @param parent Parent Widget
47      * @param name Name
48      */
49     explicit RSITimer( QObject *parent = 0 );
50 
51     // Check whether the timer is suspended.
isSuspended()52     bool isSuspended() const { return m_state == TimerState::Suspended; }
53 
tinyLeft()54     int tinyLeft() const { return m_tinyBreakCounter->counterLeft(); };
55 
bigLeft()56     int bigLeft() const { return m_bigBreakCounter->counterLeft(); };
57 
58 public slots:
59 
60     /**
61       Reads the configuration and restarts the timer with slotRestart.
62     */
63     void updateConfig( bool doRestart = false );
64 
65     /**
66       Stops the timer activity. This does not imply resetting counters.
67      */
68     void slotStop();
69 
70     /**
71       Called when the user suspends RSIBreak from the docker.
72       @param suspend If true the timer will suspend, if false the timer will unsuspend.
73     */
74     void slotSuspended( bool suspend );
75 
76     /**
77       Prepares the timer so that it can start/continue.
78      */
79     void slotStart();
80 
81     /**
82       Called when user locks the screen for pause. Resets current timers if currently suggesting.
83     */
84     void slotLock();
85 
86     /**
87       When the user presses the Skip button during a break,
88       this function will be called. It will act like a break has
89       just passed.
90     */
91     void skipBreak();
92 
93     /**
94       When the user presses the postpone break button during a break,
95       this function will be called. It will postpone the break for the
96       configured amount of seconds.
97     */
98     void postponeBreak();
99 
100     /**
101       Queries X how many seconds the user has been idle. A value of 0
102       means there was activity during the last second.
103       @returns The amount of seconds of idling.
104     */
105     int idleTime();
106 
107 private slots:
108     /**
109       The pumping heart of the timer. This will evaluate user's activity and
110       decide what to do (wait, popup a relax notification or a fullscreen break.
111     */
112     virtual void timeout();
113 
114 signals:
115     /** Enforce a fullscreen big break. */
116     void breakNow();
117 
118     /**
119       Update counters in tooltip.
120       @param tinyLeft If <=0 a tiny break is active, else it defines how
121       much time is left until the next tiny break.
122       @param bigLeft If <=0 a big break is active, else it defines how
123       much time is left until the next big break.
124     */
125     void updateToolTip( const int tinyLeft, const int bigLeft );
126 
127     /**
128       Update the time shown on the fullscreen widget.
129       @param secondsLeft Shows the user how many seconds are remaining.
130     */
131     void updateWidget( int secondsLeft );
132 
133     /**
134       Update the systray icon.
135       @param v How much time has passed until a tiny break (relative)
136                Varies from 0 to 100.
137     */
138     void updateIdleAvg( double v );
139 
140     /**
141       A request to minimize the fullscreen widget, for example when the
142       break is over.
143       @param newImage Load a new image
144     */
145     void minimize();
146 
147     /**
148       Pop up a relax notification to the user for @p sec seconds.
149       @param sec The amount of seconds the user should relax to make the
150       popup disappear. A value of -1 will hide the relax popup.
151       @param nextBreakIsBig True if the break after the next break is a big break.
152       We can warn the user in advance.
153     */
154     void relax( int sec, bool nextBreakIsBig );
155 
156     /**
157       Indicates a tinyBreak is skipped because user was enough idle
158     */
159     void tinyBreakSkipped();
160 
161     /**
162        Indicates a bigBreak is skipped because user was enough idle
163      */
164     void bigBreakSkipped();
165 
166     void startLongBreak();
167     void endLongBreak();
168     void startShortBreak();
169     void endShortBreak();
170 
171 private:
172     std::unique_ptr<RSIIdleTime> m_idleTimeInstance;
173 
174     bool m_usePopup;
175     bool m_useIdleTimers;
176     QVector<int> m_intervals;
177 
178     enum class TimerState {
179         Suspended = 0,      // user has suspended either via dbus or tray.
180         Monitoring,         // normal cycle, waiting for break to trigger.
181         Suggesting,         // politely suggest to take a break with some patience.
182         Resting             // suggestion ignored, waiting out the break.
183     } m_state;
184 
185     std::unique_ptr<RSITimerCounter> m_bigBreakCounter;
186     std::unique_ptr<RSITimerCounter> m_tinyBreakCounter;
187     std::unique_ptr<RSITimerCounter> m_pauseCounter;
188     std::unique_ptr<RSITimerCounter> m_popupCounter;
189     std::unique_ptr<RSITimerCounter> m_shortInputCounter;
190 
191     void hibernationDetector( const int totalIdle );
192     void suggestBreak( const int time );
193     void defaultUpdateToolTip();
194     void createTimers();
195 
196     // This function is called when a break has passed.
197     void resetAfterBreak();
198 
199     // Start this thread.
200     void run() override;
201 
202     /**
203       Some internal preparations for a fullscreen break window.
204       @param breakTime The amount of seconds to break.
205       @param nextBreakIsBig Whether the next break will be big.
206     */
207     void doBreakNow( const int breakTime, const bool nextBreakIsBig );
208 
209     // Constructor for tests.
210     RSITimer( std::unique_ptr<RSIIdleTime> &&_idleTime, const QVector<int> _intervals, const bool _usePopup, const bool _useIdleTimers );
211 };
212 
213 #endif
214