1
/* *************************************************************************
2
* Copyright 2012 Jakob Gruber <jakob.gruber@gmail.com> *
4
* This program is free software: you can redistribute it and/or modify *
5
* it under the terms of the GNU General Public License as published by *
6
* the Free Software Foundation, either version 2 of the License, or *
7
* (at your option) any later version. *
9
* This program is distributed in the hope that it will be useful, *
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12
* GNU General Public License for more details. *
14
* You should have received a copy of the GNU General Public License *
15
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
16
************************************************************************* */
19
#include "mainwindow.h"
21
#include <QCoreApplication>
22
#include <QGraphicsSimpleTextItem>
23
#include <QHBoxLayout>
26
#include <kactioncollection.h>
27
#include <klocalizedstring.h>
29
#include <kmessagebox.h>
30
#include <kstandardgameaction.h>
31
#include <kstatusbar.h>
32
#include <ktogglefullscreenaction.h>
34
#include "selectboardwindow.h"
35
#include "settingswindow.h"
36
#include "src/constants.h"
37
#include "src/logic/levelloader.h"
39
MainWindow::MainWindow(QWidget *parent) :
40
KXmlGuiWindow(parent),
41
m_key_pos("window/position"), m_in_progress(false), m_mode(Random)
43
QCoreApplication::setOrganizationName(ORGANIZATION_NAME);
44
QCoreApplication::setApplicationName("picmi");
46
m_timer.setInterval(500);
48
setCentralWidget(&m_view);
56
void MainWindow::setupActions() {
57
KStandardGameAction::gameNew(this, SLOT(startRandomGame()), actionCollection());
58
KStandardGameAction::load(this, SLOT(loadBoard()), actionCollection());
59
KStandardGameAction::highscores(this, SLOT(highscores()), actionCollection());
60
KStandardGameAction::quit(this, SLOT(close()), actionCollection());
61
KStandardAction::preferences(this, SLOT(settings()), actionCollection());
62
KStandardAction::fullScreen(this, SLOT(toggleFullscreen(bool)), this, actionCollection());
63
m_action_pause = KStandardGameAction::pause(this, SLOT(togglePaused(bool)), actionCollection());
64
m_action_undo = KStandardGameAction::undo(this, SLOT(undo()), actionCollection());
66
m_action_save_state = actionCollection()->addAction("save-position");
67
m_action_save_state->setText(i18n("Save Position"));
68
m_action_save_state->setIcon(KIcon("list-add"));
69
m_action_save_state->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
70
connect(m_action_save_state, SIGNAL(triggered()), this, SLOT(saveState()));
72
m_action_load_state = actionCollection()->addAction("load-position");
73
m_action_load_state->setText(i18n("Load Position"));
74
m_action_load_state->setIcon(KIcon("view-refresh"));
75
m_action_load_state->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
76
connect(m_action_load_state, SIGNAL(triggered()), this, SLOT(loadState()));
78
m_status_time = new QLabel;
79
m_status_time->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
80
m_status_position = new QLabel;
81
m_status_position->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
83
this->statusBar()->addWidget(m_status_position, 1);
84
this->statusBar()->addWidget(m_status_time, 1);
86
Kg::difficulty()->addStandardLevel(KgDifficultyLevel::Easy);
87
Kg::difficulty()->addStandardLevel(KgDifficultyLevel::Medium, true);
88
Kg::difficulty()->addStandardLevel(KgDifficultyLevel::Hard);
90
KgDifficultyLevel *configurable = new KgDifficultyLevel(90, QByteArray("Custom"), i18nc("custom difficulty", "Custom"));
91
Kg::difficulty()->addLevel(configurable);
93
KgDifficultyGUI::init(this);
94
connect(Kg::difficulty(), SIGNAL(currentLevelChanged(const KgDifficultyLevel*)), this,
95
SLOT(levelChanged(const KgDifficultyLevel*)));
97
/* Disable the toolbar configuration menu entry.
98
* The default size is used at first start up. */
99
setupGUI(QSize(700, 560), Keys | StatusBar | Save | Create);
102
void MainWindow::loadBoard() {
103
QPointer<SelectBoardWindow> w(new SelectBoardWindow(this));
104
if (w->exec() == QDialog::Accepted) {
105
startPresetGame(w->selectedBoard());
110
void MainWindow::levelChanged(const KgDifficultyLevel* level) {
111
Settings::instance()->setLevel(level->standardLevel());
112
Settings::instance()->sync();
116
void MainWindow::toggleFullscreen(bool full_screen) {
117
KToggleFullScreenAction::setFullScreen(this, full_screen);
127
void MainWindow::undoStackSizeChanged(int size)
129
m_action_undo->setEnabled(size != 0);
132
void MainWindow::saveStackSizeChanged(int size)
134
m_action_load_state->setEnabled(size != 0);
137
void MainWindow::closeEvent(QCloseEvent *event) {
139
KXmlGuiWindow::closeEvent(event);
142
void MainWindow::saveWindowState() {
144
settings.setValue(m_key_pos, pos());
148
void MainWindow::restoreWindowState() {
150
QPoint p = settings.value(m_key_pos, pos()).toPoint();
155
void MainWindow::undo() {
156
QPoint p = m_game->undo();
160
void MainWindow::saveState() {
165
void MainWindow::loadState() {
170
void MainWindow::startRandomGame() {
171
m_game = QSharedPointer<Picmi>(new Picmi());
177
void MainWindow::startPresetGame(QSharedPointer<Level> board) {
178
QSharedPointer<BoardMap> p(new BoardMap(board->width(), board->height(), board->map()));
179
m_game = QSharedPointer<Picmi>(new Picmi(p));
181
m_current_level = board;
186
void MainWindow::startGame() {
189
disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(updatePlayedTime()));
192
m_action_undo->setEnabled(false);
193
m_action_save_state->setEnabled(true);
194
m_action_load_state->setEnabled(false);
195
m_action_pause->setEnabled(true);
196
m_action_pause->setChecked(false);
197
Kg::difficulty()->setGameRunning(true);
200
m_scene = m_view.createScene(m_game);
204
m_view.setEnabled(true);
206
m_view.setPaused(false);
208
connect(&m_timer, SIGNAL(timeout()), this, SLOT(updatePlayedTime()));
209
connect(m_game.data(), SIGNAL(stateChanged()), this, SLOT(updatePositions()));
210
connect(m_game.data(), SIGNAL(gameWon()), this, SLOT(gameWon()));
211
connect(m_game.data(), SIGNAL(undoStackSizeChanged(int)), this, SLOT(undoStackSizeChanged(int)));
212
connect(m_game.data(), SIGNAL(saveStackSizeChanged(int)), this, SLOT(saveStackSizeChanged(int)));
214
m_in_progress = true;
217
void MainWindow::updatePlayedTime() {
218
m_status_time->setText(i18n("Elapsed time: %1",
219
Time(m_game->elapsedSecs()).toString()));
222
void MainWindow::updatePositions() {
223
m_status_position->setText(i18n("Actions since last saved position: %1",
224
m_game->currentStateAge()));
227
QSharedPointer<KScoreDialog> MainWindow::createScoreDialog() {
228
QSharedPointer<KScoreDialog> p(new KScoreDialog(KScoreDialog::Name | KScoreDialog::Date | KScoreDialog::Time));
230
p->initFromDifficulty(Kg::difficulty());
231
p->hideField(KScoreDialog::Score);
236
void MainWindow::gameWon() {
237
KScoreDialog::FieldInfo score = m_game->endGame();
238
m_view.setEnabled(false);
239
m_action_pause->setEnabled(false);
240
m_action_undo->setEnabled(false);
241
m_action_save_state->setEnabled(false);
242
m_action_load_state->setEnabled(false);
243
Kg::difficulty()->setGameRunning(false);
245
m_in_progress = false;
247
bool notified = false;
248
if (m_mode == Random && Kg::difficultyLevel() != KgDifficultyLevel::Custom) {
249
QSharedPointer<KScoreDialog> scoreDialog = createScoreDialog();
250
if (scoreDialog->addScore(score, KScoreDialog::LessIsMore | KScoreDialog::AskName) != 0) {
254
} else if (m_mode == Preset) {
255
m_current_level->setSolved(m_game->elapsedSecs());
258
/* Ensure that the user gets some kind of feedback about solving the board. */
260
KMessageBox::information(this, i18n("Board Solved!"),
261
i18n("Congratulations, you've solved this board!"));
267
void MainWindow::highscores() {
270
QSharedPointer<KScoreDialog> scoreDialog = createScoreDialog();
276
void MainWindow::togglePaused(bool paused) {
277
m_view.setPaused(paused);
278
m_action_undo->setEnabled(!paused);
279
m_action_save_state->setEnabled(!paused);
280
m_action_load_state->setEnabled(!paused);
289
void MainWindow::pauseGame() {
290
if (m_action_pause->isChecked() || !m_in_progress) {
294
m_action_pause->setChecked(true);
298
void MainWindow::settings() {
301
QPointer<SettingsWindow> w(new SettingsWindow(this));