1 /***********************************************************************
2 *
3 * Copyright (C) 2009, 2012, 2014 Graeme Gott <graeme@gottcode.org>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 ***********************************************************************/
19
20 #include "score_board.h"
21
22 #include <QDialogButtonBox>
23 #include <QHeaderView>
24 #include <QSettings>
25 #include <QTime>
26 #include <QTreeWidget>
27 #include <QVBoxLayout>
28
29 #include <cmath>
30
ScoreBoard(QWidget * parent)31 ScoreBoard::ScoreBoard(QWidget* parent)
32 : QDialog(parent) {
33 setWindowTitle(tr("Scores"));
34
35 // Create tree view
36 m_scores = new QTreeWidget(this);
37 m_scores->setHeaderLabels(QStringList() << tr("Score") << tr("Time") << tr("Words") << tr("Length"));
38 m_scores->header()->setSectionsMovable(false);
39 m_scores->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
40 m_scores->header()->setStretchLastSection(false);
41 m_scores->setRootIsDecorated(false);
42
43 // Load scores
44 QStringList scores = QSettings().value("Scores/Values").toStringList();
45 if (!scores.isEmpty() && scores.count() % 3 == 0) {
46 for (int i = 0; i < scores.count(); i += 3) {
47 createScoreItem(scores[i].toInt(), scores[i + 1].toInt(), scores[i + 2].toInt());
48 }
49 }
50
51 // Create OK button
52 QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this);
53 connect(buttons, &QDialogButtonBox::rejected, this, &ScoreBoard::reject);
54
55 // Layout window
56 QVBoxLayout* layout = new QVBoxLayout(this);
57 layout->addWidget(m_scores);
58 layout->addWidget(buttons);
59
60 // Resize window
61 resize(QSettings().value("Scores/Size", sizeHint()).toSize());
62 }
63
64 //-----------------------------------------------------------------------------
65
addScore(int secs,int count,int length)66 void ScoreBoard::addScore(int secs, int count, int length) {
67 // Add score to list
68 QTreeWidgetItem* item = createScoreItem(secs, count, length);
69 if (item == 0) {
70 return;
71 }
72 m_scores->clearSelection();
73 item->setSelected(true);
74
75 // Save scores
76 QStringList scores;
77 for (int i = 0; i < m_scores->topLevelItemCount(); ++i) {
78 item = m_scores->topLevelItem(i);
79 scores.append(item->data(1, Qt::UserRole).toString());
80 scores.append(item->text(2));
81 scores.append(item->text(3));
82 }
83 QSettings().setValue("Scores/Values", scores);
84
85 show();
86 }
87
88 //-----------------------------------------------------------------------------
89
hideEvent(QHideEvent * event)90 void ScoreBoard::hideEvent(QHideEvent* event) {
91 QSettings().setValue("Scores/Size", size());
92 QDialog::hideEvent(event);
93 }
94
95 //-----------------------------------------------------------------------------
96
createScoreItem(int secs,int count,int length)97 QTreeWidgetItem* ScoreBoard::createScoreItem(int secs, int count, int length) {
98 // Calculate score
99 if (secs == 0) {
100 return 0;
101 }
102 int score = std::lround((count * length * 120.0) / secs);
103 if (score == 0) {
104 return 0;
105 }
106
107 // Find position
108 int pos = 0;
109 for (pos = 0; pos < m_scores->topLevelItemCount(); ++pos) {
110 if (score > m_scores->topLevelItem(pos)->text(0).toInt()) {
111 break;
112 }
113 }
114 if (pos >= 10) {
115 return 0;
116 }
117
118 // Create item
119 QTime time = QTime(0, 0, 0).addSecs(secs);
120 QTreeWidgetItem* item = new QTreeWidgetItem(QStringList() << QString::number(score) << time.toString("hh:mm:ss") << QString::number(count) << QString::number(length));
121 item->setData(1, Qt::UserRole, secs);
122 item->setTextAlignment(0, Qt::AlignRight | Qt::AlignVCenter);
123 item->setTextAlignment(1, Qt::AlignRight | Qt::AlignVCenter);
124 item->setTextAlignment(2, Qt::AlignRight | Qt::AlignVCenter);
125 item->setTextAlignment(3, Qt::AlignRight | Qt::AlignVCenter);
126
127 // Add item
128 if (m_scores->topLevelItemCount() == 10) {
129 delete m_scores->takeTopLevelItem(9);
130 }
131 m_scores->insertTopLevelItem(pos, item);
132
133 return item;
134 }
135