~ubuntu-branches/ubuntu/utopic/picmi/utopic

« back to all changes in this revision

Viewing changes to src/gui/mainwindow.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2012-12-03 17:39:47 UTC
  • Revision ID: package-import@ubuntu.com-20121203173947-tt1kk5wp92zk1f2z
Tags: upstream-4.9.90
ImportĀ upstreamĀ versionĀ 4.9.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* *************************************************************************
 
2
 *  Copyright 2012 Jakob Gruber <jakob.gruber@gmail.com>                   *
 
3
 *                                                                         *
 
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.                                    *
 
8
 *                                                                         *
 
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.                           *
 
13
 *                                                                         *
 
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
 ************************************************************************* */
 
17
 
 
18
 
 
19
#include "mainwindow.h"
 
20
 
 
21
#include <QCoreApplication>
 
22
#include <QGraphicsSimpleTextItem>
 
23
#include <QHBoxLayout>
 
24
#include <QPointer>
 
25
#include <iostream>
 
26
#include <kactioncollection.h>
 
27
#include <klocalizedstring.h>
 
28
#include <kmenubar.h>
 
29
#include <kmessagebox.h>
 
30
#include <kstandardgameaction.h>
 
31
#include <kstatusbar.h>
 
32
#include <ktogglefullscreenaction.h>
 
33
 
 
34
#include "selectboardwindow.h"
 
35
#include "settingswindow.h"
 
36
#include "src/constants.h"
 
37
#include "src/logic/levelloader.h"
 
38
 
 
39
MainWindow::MainWindow(QWidget *parent) :
 
40
    KXmlGuiWindow(parent),
 
41
    m_key_pos("window/position"), m_in_progress(false), m_mode(Random)
 
42
{
 
43
    QCoreApplication::setOrganizationName(ORGANIZATION_NAME);
 
44
    QCoreApplication::setApplicationName("picmi");
 
45
 
 
46
    m_timer.setInterval(500);
 
47
 
 
48
    setCentralWidget(&m_view);
 
49
 
 
50
    setupActions();
 
51
    restoreWindowState();
 
52
 
 
53
    startRandomGame();
 
54
}
 
55
 
 
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());
 
65
 
 
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()));
 
71
 
 
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()));
 
77
 
 
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);
 
82
 
 
83
    this->statusBar()->addWidget(m_status_position, 1);
 
84
    this->statusBar()->addWidget(m_status_time, 1);
 
85
 
 
86
    Kg::difficulty()->addStandardLevel(KgDifficultyLevel::Easy);
 
87
    Kg::difficulty()->addStandardLevel(KgDifficultyLevel::Medium, true);
 
88
    Kg::difficulty()->addStandardLevel(KgDifficultyLevel::Hard);
 
89
 
 
90
    KgDifficultyLevel *configurable = new KgDifficultyLevel(90, QByteArray("Custom"), i18nc("custom difficulty", "Custom"));
 
91
    Kg::difficulty()->addLevel(configurable);
 
92
 
 
93
    KgDifficultyGUI::init(this);
 
94
    connect(Kg::difficulty(), SIGNAL(currentLevelChanged(const KgDifficultyLevel*)), this,
 
95
            SLOT(levelChanged(const KgDifficultyLevel*)));
 
96
 
 
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);
 
100
}
 
101
 
 
102
void MainWindow::loadBoard() {
 
103
    QPointer<SelectBoardWindow> w(new SelectBoardWindow(this));
 
104
    if (w->exec() == QDialog::Accepted) {
 
105
        startPresetGame(w->selectedBoard());
 
106
    }
 
107
    delete w;
 
108
}
 
109
 
 
110
void MainWindow::levelChanged(const KgDifficultyLevel* level) {
 
111
    Settings::instance()->setLevel(level->standardLevel());
 
112
    Settings::instance()->sync();
 
113
    startRandomGame();
 
114
}
 
115
 
 
116
void MainWindow::toggleFullscreen(bool full_screen) {
 
117
    KToggleFullScreenAction::setFullScreen(this, full_screen);
 
118
    if (full_screen) {
 
119
        menuBar()->hide();
 
120
        statusBar()->hide();
 
121
    } else {
 
122
        menuBar()->show();
 
123
        statusBar()->show();
 
124
    }
 
125
}
 
126
 
 
127
void MainWindow::undoStackSizeChanged(int size)
 
128
{
 
129
    m_action_undo->setEnabled(size != 0);
 
130
}
 
131
 
 
132
void MainWindow::saveStackSizeChanged(int size)
 
133
{
 
134
    m_action_load_state->setEnabled(size != 0);
 
135
}
 
136
 
 
137
void MainWindow::closeEvent(QCloseEvent *event) {
 
138
    saveWindowState();
 
139
    KXmlGuiWindow::closeEvent(event);
 
140
}
 
141
 
 
142
void MainWindow::saveWindowState() {
 
143
    QSettings settings;
 
144
    settings.setValue(m_key_pos, pos());
 
145
    settings.sync();
 
146
}
 
147
 
 
148
void MainWindow::restoreWindowState() {
 
149
    QSettings settings;
 
150
    QPoint p = settings.value(m_key_pos, pos()).toPoint();
 
151
 
 
152
    move(p);
 
153
}
 
154
 
 
155
void MainWindow::undo() {
 
156
    QPoint p = m_game->undo();
 
157
    m_scene->refresh(p);
 
158
}
 
159
 
 
160
void MainWindow::saveState() {
 
161
    m_game->saveState();
 
162
    updatePositions();
 
163
}
 
164
 
 
165
void MainWindow::loadState() {
 
166
    m_game->loadState();
 
167
    m_scene->refresh();
 
168
}
 
169
 
 
170
void MainWindow::startRandomGame() {
 
171
    m_game = QSharedPointer<Picmi>(new Picmi());
 
172
    m_mode = Random;
 
173
 
 
174
    startGame();
 
175
}
 
176
 
 
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));
 
180
    m_mode = Preset;
 
181
    m_current_level = board;
 
182
 
 
183
    startGame();
 
184
}
 
185
 
 
186
void MainWindow::startGame() {
 
187
 
 
188
    if (m_scene) {
 
189
        disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(updatePlayedTime()));
 
190
    }
 
191
 
 
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);
 
198
 
 
199
    m_timer.start();
 
200
    m_scene = m_view.createScene(m_game);
 
201
    updatePlayedTime();
 
202
    updatePositions();
 
203
 
 
204
    m_view.setEnabled(true);
 
205
    m_view.setFocus();
 
206
    m_view.setPaused(false);
 
207
 
 
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)));
 
213
 
 
214
    m_in_progress = true;
 
215
}
 
216
 
 
217
void MainWindow::updatePlayedTime() {
 
218
    m_status_time->setText(i18n("Elapsed time: %1",
 
219
                                Time(m_game->elapsedSecs()).toString()));
 
220
}
 
221
 
 
222
void MainWindow::updatePositions() {
 
223
    m_status_position->setText(i18n("Actions since last saved position: %1",
 
224
                                    m_game->currentStateAge()));
 
225
}
 
226
 
 
227
QSharedPointer<KScoreDialog> MainWindow::createScoreDialog() {
 
228
    QSharedPointer<KScoreDialog> p(new KScoreDialog(KScoreDialog::Name | KScoreDialog::Date | KScoreDialog::Time));
 
229
 
 
230
    p->initFromDifficulty(Kg::difficulty());
 
231
    p->hideField(KScoreDialog::Score);
 
232
 
 
233
    return p;
 
234
}
 
235
 
 
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);
 
244
    m_timer.stop();
 
245
    m_in_progress = false;
 
246
 
 
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) {
 
251
            scoreDialog->exec();
 
252
            notified = true;
 
253
        }
 
254
    } else if (m_mode == Preset) {
 
255
        m_current_level->setSolved(m_game->elapsedSecs());
 
256
    }
 
257
 
 
258
    /* Ensure that the user gets some kind of feedback about solving the board. */
 
259
    if (!notified) {
 
260
        KMessageBox::information(this, i18n("Board Solved!"),
 
261
                                 i18n("Congratulations, you've solved this board!"));
 
262
    }
 
263
 
 
264
    m_view.setFocus();
 
265
}
 
266
 
 
267
void MainWindow::highscores() {
 
268
    pauseGame();
 
269
 
 
270
    QSharedPointer<KScoreDialog> scoreDialog = createScoreDialog();
 
271
    scoreDialog->exec();
 
272
 
 
273
    m_view.setFocus();
 
274
}
 
275
 
 
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);
 
281
 
 
282
    if (paused) {
 
283
        m_timer.stop();
 
284
    } else {
 
285
        m_timer.start();
 
286
    }
 
287
}
 
288
 
 
289
void MainWindow::pauseGame() {
 
290
    if (m_action_pause->isChecked() || !m_in_progress) {
 
291
        return;
 
292
    }
 
293
 
 
294
    m_action_pause->setChecked(true);
 
295
    togglePaused(true);
 
296
}
 
297
 
 
298
void MainWindow::settings() {
 
299
    pauseGame();
 
300
 
 
301
    QPointer<SettingsWindow> w(new SettingsWindow(this));
 
302
    w->exec();
 
303
    delete w;
 
304
}