-
Notifications
You must be signed in to change notification settings - Fork 0
/
Timer.cpp
154 lines (131 loc) · 5.02 KB
/
Timer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// SC2 Metronome, a tool for improving mechanics in StarCraft(R) II
// Copyright (C) 2016 Martial Demolins AKA Folco
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
// as published by the Free Software foundation, either version 3 of the License, or (at your option) any later version.
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program.
// If not, see <http://www.gnu.org/licenses/>.
#include "SMException.hpp"
#include "MainWindow.hpp"
#include "Timer.hpp"
#include "Log.hpp"
#include <QMediaPlaylist>
#include <versionhelpers.h>
Timer::Timer(QString filename, int period, QKeySequence keySequence, UINT modifiers, UINT virtualKey, unsigned int hotkeyId)
: filename(filename)
, period(period)
, keySequence(keySequence)
, modifiers(modifiers)
, virtualKey(virtualKey)
, hotkeyId(hotkeyId)
, broken(false)
{
// Register the hotkey (add the MOD_NOREPEAT flag)
if (!RegisterHotKey(nullptr, hotkeyId, modifiers | getNoRepeatFlag(), virtualKey)) {
throw SMException(tr("failed to register the hotkey."));
}
// Create the player, the playlist and the media container
this->mediaContent = new QMediaContent(filename);
this->player = new QMediaPlayer(this);
QMediaPlaylist* playlist = new QMediaPlaylist(this);
// Give the media to the playlist, and the playlist to the player
playlist->addMedia(*mediaContent);
playlist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce);
player->setMedia(playlist);
// Create the timer
this->timer = new QTimer(this);
this->timer->setInterval(period * 1000);
// Connections
connect(this->player, &QMediaPlayer::mediaStatusChanged, this, &Timer::mediaStatusChanged);
connect(this->player, static_cast<void (QMediaPlayer::*)(QMediaPlayer::Error)>(&QMediaPlayer::error), this, &Timer::error);
connect(this->timer, &QTimer::timeout, this, &Timer::playSound);
connect(MainWindow::instance()->getNativeEventFilter(), &NativeEventFilter::hotkeyReceived, this, &Timer::togglePlayStop);
}
Timer::~Timer()
{
UnregisterHotKey(nullptr, this->hotkeyId);
delete this->mediaContent;
}
// Method called when the timer has been edited
void Timer::setNewData(int period, QKeySequence keySequence, UINT modifiers, UINT virtualKey, int hotkeyId)
{
// First, try to register the new hotkey if needed
if ((this->virtualKey != virtualKey) || (this->modifiers != modifiers)) {
if (!RegisterHotKey(nullptr, hotkeyId, modifiers | getNoRepeatFlag(), virtualKey)) {
throw SMException(tr("failed to register the hotkey. No modification done."));
}
UnregisterHotKey(nullptr, this->hotkeyId);
this->hotkeyId = hotkeyId;
}
// Stop the timer if it's currently active
bool active = this->timer->isActive();
stop();
// Update timer's data
timer->setInterval(period * 1000);
this->period = period;
this->keySequence = keySequence;
this->modifiers = modifiers;
this->virtualKey = virtualKey;
// Enable the timer if it was previously active
if (active) {
play();
}
}
// Windows Vista doesn't support the NO_REPEAT_FLAG
UINT Timer::getNoRepeatFlag() const
{
UINT flag = 0x0000;
if (IsWindows7OrGreater()) {
flag = 0x4000;
}
return flag;
}
// Slots called when an event occurs to the player
void Timer::mediaStatusChanged(QMediaPlayer::MediaStatus status)
{
if (status == QMediaPlayer::InvalidMedia) {
setBroken();
}
}
void Timer::error(QMediaPlayer::Error error)
{
if (error != QMediaPlayer::NoError) {
setBroken();
}
}
void Timer::setBroken()
{
// Disconnect the timer from the hotkey handler and stop it
disconnect(MainWindow::instance()->getNativeEventFilter(), &NativeEventFilter::hotkeyReceived, this, &Timer::togglePlayStop);
this->broken = true;
this->timer->stop();
this->player->stop();
MainWindow::instance()->setTimerStatus(this, STATUS_BROKEN);
}
// Triggerred when the hotkey is pressed
void Timer::togglePlayStop(int hotkeyId)
{
if (this->hotkeyId == hotkeyId) {
this->timer->isActive() ? stop() : play();
}
}
// Start and stop the Timer
void Timer::play()
{
MainWindow::instance()->setTimerStatus(this, STATUS_PLAYING);
this->timer->start();
playSound();
}
void Timer::stop()
{
MainWindow::instance()->setTimerStatus(this, STATUS_STOPPED);
this->timer->stop();
this->player->stop();
}
// Play the sound, ensuring that it's stopped
void Timer::playSound()
{
this->player->stop();
this->player->play();
}