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