Skip to content

Commit 3e5288b

Browse files
committed
Version 0.2
* Added button to remove a call. * Added little delay between adding or removing calls. * Added about menu. * Added auto-saving on 5 minutes. * Added button to take a screenshot. (Not quite useful, but added just for fun :). * Added some shortcuts for each button. * Using English as primary language, and using tr() to translate. * Fixed little bug when setting today's calls. If it's the first time we open the program, it throws an error message 'not position on a valid record', and even though the program didn't use to crash, that shouldn't be taken slightly.
1 parent feaf326 commit 3e5288b

File tree

4 files changed

+241
-26
lines changed

4 files changed

+241
-26
lines changed

CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.5)
22

3-
project(CallsCounter VERSION 0.1 LANGUAGES CXX)
3+
project(CallsCounter VERSION 0.2 LANGUAGES CXX)
44

55
set(CMAKE_AUTOUIC ON)
66
set(CMAKE_AUTOMOC ON)
@@ -9,6 +9,12 @@ set(CMAKE_AUTORCC ON)
99
set(CMAKE_CXX_STANDARD 17)
1010
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1111

12+
add_compile_definitions(PROGRAM_NAME="CallsCounter")
13+
add_compile_definitions(VERSION="0.2")
14+
add_compile_definitions(AUTHOR="Brayan MS")
15+
add_compile_definitions(THIS_PROGRAM_URL="https://github.com/brookiestein/CallsCounter")
16+
add_compile_definitions(OTHER_PROJECTS="https://github.com/brookiestein?tab=repositories")
17+
1218
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Sql)
1319
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Sql)
1420

mainwindow.cpp

Lines changed: 138 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,41 @@ MainWindow::MainWindow(QWidget *parent)
66
, m_ui(new Ui::MainWindow)
77
, m_calls(0)
88
, m_db()
9+
, m_lock(false)
910
{
1011
m_ui->setupUi(this);
1112

1213
connect(&m_db, &Database::error, this, &MainWindow::error);
14+
connect(m_ui->actionAbout, &QAction::triggered, this, &MainWindow::about);
1315
connect(m_ui->newButton, &QPushButton::clicked, this, &MainWindow::newCall);
16+
connect(m_ui->removeButton, &QPushButton::clicked, this, &MainWindow::removeCall);
1417
connect(m_ui->saveButton, &QPushButton::clicked, this, &MainWindow::saveCalls);
15-
connect(&m_timer, &QTimer::timeout, this, &MainWindow::setDateTime);
18+
connect(&m_saverTimer, &QTimer::timeout, this, &MainWindow::saveCalls);
19+
connect(&m_saverTimer1s, &QTimer::timeout, this, &MainWindow::setRemainingTimeLabel);
20+
connect(&m_datetimeTimer, &QTimer::timeout, this, &MainWindow::setDateTime);
21+
connect(m_ui->screenshotButton, &QPushButton::clicked, this, &MainWindow::saveScreenShot);
22+
connect(&m_lockerTimer, &QTimer::timeout, this, &MainWindow::unlockNewButton);
1623

1724
m_username = qgetenv("USER");
1825
if (m_username.isEmpty())
1926
m_username = qgetenv("USERNAME");
20-
m_ui->usernameLabel->setText("Usuario: " + m_username);
27+
m_ui->usernameLabel->setText(tr("User: ") + m_username);
2128

2229
setDateTime();
2330
setTodaysCalls();
2431

25-
m_timer.setInterval(1'000);
26-
m_timer.start();
32+
m_lockerTimer.setInterval(5'000);
33+
m_saverTimer.setInterval(300'000); // 5 minutes.
34+
m_saverTimer1s.setInterval(1'000);
35+
m_datetimeTimer.setInterval(1'000);
36+
m_datetimeTimer.start();
37+
m_saverTimer.start();
38+
m_saverTimer1s.start();
39+
40+
m_ui->newButton->setShortcut(Qt::CTRL | Qt::Key_A);
41+
m_ui->removeButton->setShortcut(Qt::CTRL | Qt::Key_R);
42+
m_ui->screenshotButton->setShortcut(Qt::CTRL | Qt::Key_P);
43+
m_ui->saveButton->setShortcut(Qt::CTRL | Qt::Key_S);
2744
}
2845

2946
MainWindow::~MainWindow()
@@ -33,20 +50,29 @@ MainWindow::~MainWindow()
3350

3451
void MainWindow::setLabel()
3552
{
36-
m_ui->messageLabel->setText(QString("Hoy has registrado %1 %2.")
37-
.arg(QString::number(m_calls), m_calls == 1 ? "llamada" : "llamadas"));
53+
m_ui->messageLabel->setText(tr("You've registered %1 %2 today.")
54+
.arg(QString::number(m_calls), m_calls == 1 ? tr("call") : tr("calls")));
3855
}
3956

4057
void MainWindow::setDateTime()
4158
{
4259
m_datetime = QDateTime::currentDateTime().toString("dd-MM-yyyy");
43-
m_ui->datetimeLabel->setText(QString("Fecha: %1").arg(m_datetime));
60+
auto time = QDateTime::currentDateTime().toString("hh:mm:ss");
61+
m_ui->datetimeLabel->setText(tr("Date: %1 %2").arg(m_datetime, time));
4462
}
4563

4664
void MainWindow::setTodaysCalls()
4765
{
4866
if (not m_db.open())
4967
return;
68+
// shouldUpdate() will help us because it checks if there's at least one record in the database.
69+
// If there aren't any, we'll get 'not positioned on a valid record' error message, so to avoid this:
70+
if (not shouldUpdate()) {
71+
m_db.close();
72+
setLabel();
73+
return;
74+
}
75+
5076
auto statement = QString("SELECT id, calls FROM Calls WHERE date='%1' ORDER BY id DESC LIMIT 1").arg(m_datetime);
5177
if (not m_db.exec(statement)) {
5278
m_db.close();
@@ -82,24 +108,70 @@ bool MainWindow::shouldUpdate()
82108
return true;
83109
}
84110

111+
void MainWindow::about(bool checked)
112+
{
113+
Q_UNUSED(checked);
114+
auto message = tr("<p>Version: %1</p>\
115+
<p>Author: %2</p>\
116+
<a href=\"%3\">This software</a><br>\
117+
<a href=\"%4\">Other projects</a>").arg(VERSION, AUTHOR, THIS_PROGRAM_URL, OTHER_PROJECTS);
118+
QMessageBox msgBox(this);
119+
msgBox.setWindowTitle(PROGRAM_NAME);
120+
msgBox.setTextFormat(Qt::RichText);
121+
msgBox.setText(message);
122+
msgBox.exec();
123+
}
124+
125+
void MainWindow::unlockNewButton()
126+
{
127+
m_lock = false;
128+
}
129+
85130
void MainWindow::newCall()
86131
{
132+
if (m_lock) {
133+
QMessageBox::warning(this, tr("Warning"), tr("You have to wait a couple of secs to register a new call."));
134+
return;
135+
} else {
136+
m_lock = true;
137+
m_lockerTimer.start();
138+
}
139+
87140
++m_calls;
88141
setLabel();
89142
}
90143

144+
void MainWindow::removeCall()
145+
{
146+
if (m_lock) {
147+
QMessageBox::warning(this, tr("Warning"), tr("You have to wait a couple of secs to remove a call."));
148+
return;
149+
} else {
150+
m_lock = true;
151+
m_lockerTimer.start();
152+
}
153+
154+
if (m_calls == 0) {
155+
error(tr("Registered calls cannot be below zero."));
156+
return;
157+
}
158+
159+
--m_calls;
160+
setLabel();
161+
}
162+
91163
void MainWindow::saveCalls()
92164
{
93165
if (not m_db.open())
94166
return;
95167

96-
bool update = shouldUpdate();
168+
bool update { shouldUpdate() };
97169
QString statement;
98170

99171
if (update) {
100-
// I prefer to use IDs in the WHERE clause, but we have no problem since datetime cannot be duplicated.
101-
statement = QString("UPDATE Calls SET calls='%1' WHERE username='%2' AND date='%3'")
102-
.arg(QString::number(m_calls), m_username, m_datetime);
172+
// I prefer to use the id in the WHERE clause, but we have no problem since date cannot be duplicated.
173+
statement = QString("UPDATE Calls SET calls='%1' WHERE date='%2' AND username='%3'")
174+
.arg(QString::number(m_calls), m_datetime, m_username);
103175
} else {
104176
statement = QString("INSERT INTO Calls (calls, date, username) VALUES ('%1', '%2', '%3')")
105177
.arg(QString::number(m_calls), m_datetime, m_username);
@@ -112,5 +184,59 @@ void MainWindow::saveCalls()
112184

113185
m_db.close();
114186

115-
QMessageBox::information(this, "Information", "Calls have been saved.");
187+
if (sender() == m_ui->saveButton) {
188+
QMessageBox::information(this, tr("Information"), tr("Calls have been saved."));
189+
}
190+
191+
m_saverTimer.start();
192+
}
193+
194+
QPixmap MainWindow::takeScreenShot()
195+
{
196+
QRect rect { geometry() };
197+
int x { rect.x() };
198+
int y { rect.y() };
199+
int width { rect.width() };
200+
int height { rect.height() };
201+
QScreen* s { screen() };
202+
QPixmap pixmap { s->grabWindow(0, x, y, width, height) };
203+
return pixmap;
204+
}
205+
206+
void MainWindow::saveScreenShot()
207+
{
208+
auto filename { QFileDialog::getSaveFileName(this, tr("Save screenshot"), tr("Images (*.png *.jpg *.jpeg)")) };
209+
if (filename.isEmpty()) {
210+
QMessageBox::warning(this, tr("Warning"), tr("Not saving screenshot."));
211+
return;
212+
}
213+
214+
if (not filename.endsWith(".png") and not filename.endsWith(".jpg") and not filename.endsWith(".jpeg"))
215+
filename += ".png";
216+
217+
if (QFile file(filename); file.exists()) {
218+
auto answer = QMessageBox::question(this, tr("Confirm"), tr("File %1 exists. Do you want to overload it?").arg(filename));
219+
if (answer != QMessageBox::Yes)
220+
return;
221+
}
222+
223+
auto pixmap { takeScreenShot() };
224+
pixmap.save(filename, "PNG");
225+
QMessageBox::information(this, tr("Information"), tr("Screenshot saved."));
226+
}
227+
228+
void MainWindow::setRemainingTimeLabel()
229+
{
230+
int milliseconds { m_saverTimer.remainingTime() };
231+
QString minutes;
232+
233+
{
234+
int s = milliseconds / 1'000;
235+
int m = s / 60;
236+
minutes = QString::number(m);
237+
}
238+
239+
auto label { tr("Saving calls on %1 minute%2").arg(minutes, (minutes == "1" ? "." : "s.")) };
240+
m_ui->remainingTimeLabel->setText(label);
241+
m_saverTimer1s.start();
116242
}

mainwindow.hpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@
33

44
#include <QDateTime>
55
#include <QDir>
6+
#include <QFile>
7+
#include <QFileDialog>
68
#include <QMainWindow>
79
#include <QMessageBox>
10+
#include <QPixmap>
11+
#include <QRect>
12+
#include <QScreen>
813
#include <QSqlRecord>
914
#include <QTimer>
1015

@@ -21,20 +26,30 @@ class MainWindow : public QMainWindow
2126
int m_calls;
2227
QString m_datetime;
2328
QString m_username;
24-
QTimer m_timer; // To set datetime.
29+
QTimer m_lockerTimer;
30+
QTimer m_saverTimer;
31+
QTimer m_saverTimer1s;
32+
QTimer m_datetimeTimer;
33+
bool m_lock;
2534
Database m_db;
2635

2736
void setLabel();
2837
void setDateTime();
2938
void setTodaysCalls();
3039
bool shouldUpdate();
40+
QPixmap takeScreenShot();
3141
public:
3242
MainWindow(QWidget* parent = nullptr);
3343
~MainWindow();
3444
private slots:
45+
void about(bool checked);
46+
void unlockNewButton();
3547
void error(const QString& message);
3648
void newCall();
49+
void removeCall();
3750
void saveCalls();
51+
void saveScreenShot();
52+
void setRemainingTimeLabel();
3853
};
3954

4055
#endif // MAINWINDOW_H

0 commit comments

Comments
 (0)