~ubuntu-branches/ubuntu/precise/kdegames/precise

« back to all changes in this revision

Viewing changes to kshisen/app.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sune Vuorela
  • Date: 2009-04-06 01:33:00 UTC
  • mfrom: (1.1.3 upstream)
  • mto: (2.2.2 squeeze)
  • mto: This revision was merged to the branch mainline in revision 51.
  • Revision ID: james.westby@ubuntu.com-20090406013300-5d62yspscjsv5zd6
Tags: 4:4.2.2-1
* New upstream release:
  - Bugfixes in kpat. (Closes: #376420, #444050, #291007, #422437, #448641)
  - kmines, it is not longer possible cheat the timer. (Closes: #409310)
  - knetwalk, game type is shown after restart. (Closes: #417837)
* Bump build-deps.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Yo Emacs, this is -*- C++ -*-
 
2
 *******************************************************************
 
3
 *******************************************************************
 
4
 *
 
5
 *
 
6
 * KSHISEN
 
7
 *
 
8
 *
 
9
 *******************************************************************
 
10
 *
 
11
 * A japanese game similar to mahjongg
 
12
 *
 
13
 *******************************************************************
 
14
 *
 
15
 * Copyright (C)  1997 by Mario Weilguni <mweilguni@sime.com>
 
16
 * Copyright (C) 2002-2004 Dave Corrie  <kde@davecorrie.com>
 
17
 * Copyright (C) 2007 Mauricio Piacentini <mauricio@tabuleiro.com>
 
18
 *
 
19
 *******************************************************************
 
20
 *
 
21
 * This file is part of the KDE project "KSHISEN"
 
22
 *
 
23
 * KSHISEN is free software; you can redistribute it and/or modify
 
24
 * it under the terms of the GNU General Public License as published by
 
25
 * the Free Software Foundation; either version 2, or (at your option)
 
26
 * any later version.
 
27
 *
 
28
 * KSHISEN is distributed in the hope that it will be useful,
 
29
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
30
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
31
 * GNU General Public License for more details.
 
32
 *
 
33
 * You should have received a copy of the GNU General Public License
 
34
 * along with KSHISEN; see the file COPYING.  If not, write to
 
35
 * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 
36
 * Boston, MA 02110-1301, USA.
 
37
 *
 
38
 *******************************************************************
 
39
 */
 
40
 
 
41
#include "app.h"
 
42
 
 
43
#include <kactioncollection.h>
 
44
#include <kstandardaction.h>
 
45
#include <kseparator.h>
 
46
#include <kmessagebox.h>
 
47
#include <kconfig.h>
 
48
#include <kaction.h>
 
49
#include <kstandardgameaction.h>
 
50
#include <khighscore.h>
 
51
#include <kdebug.h>
 
52
#include <kshortcutsdialog.h>
 
53
#include <kmenu.h>
 
54
#include <kstatusbar.h>
 
55
#include <klocale.h>
 
56
#include <kpushbutton.h>
 
57
#include <KStandardGuiItem>
 
58
#include <kconfigdialog.h>
 
59
 
 
60
#include <QTimer>
 
61
#include <KLineEdit>
 
62
 
 
63
#include <cmath>
 
64
#include <kglobal.h>
 
65
#include "prefs.h"
 
66
#include "ui_settings.h"
 
67
 
 
68
#include <kmahjonggconfigdialog.h>
 
69
 
 
70
class Settings : public QWidget, public Ui::Settings
 
71
{
 
72
public:
 
73
        Settings(QWidget *parent)
 
74
                : QWidget(parent)
 
75
        {
 
76
                setupUi(this);
 
77
        }
 
78
};
 
79
 
 
80
App::App(QWidget *parent) : KXmlGuiWindow(parent),
 
81
   cheat(false)
 
82
{
 
83
        highscoreTable = new KHighscore(this);
 
84
 
 
85
        // TODO?
 
86
        // Would it make sense long term to have a kconfig update rather then
 
87
        // havin both formats supported in the code?
 
88
        if(highscoreTable->hasTable())
 
89
                readHighscore();
 
90
        else
 
91
                readOldHighscore();
 
92
 
 
93
        setupStatusBar();
 
94
        setupActions();
 
95
 
 
96
        board = new Board(this);
 
97
        board->setObjectName( "board" );
 
98
 
 
99
        setCentralWidget(board);
 
100
 
 
101
        setupGUI();
 
102
 
 
103
        connect(board, SIGNAL(changed()), this, SLOT(enableItems()));
 
104
        connect(board, SIGNAL(tilesDontMatch()), this, SLOT(notifyTilesDontMatch()));
 
105
        connect(board, SIGNAL(invalidMove()), this, SLOT(notifyInvalidMove()));
 
106
        connect(board, SIGNAL(selectATile()), this, SLOT(notifySelectATile()));
 
107
        connect(board, SIGNAL(selectAMatchingTile()), this, SLOT(notifySelectAMatchingTile()));
 
108
        connect(board, SIGNAL(selectAMove()), this, SLOT(notifySelectAMove()));
 
109
 
 
110
        QTimer *t = new QTimer(this);
 
111
        t->start(1000);
 
112
        connect(t, SIGNAL(timeout()), this, SLOT(updateScore()));
 
113
        connect(board, SIGNAL(endOfGame()), this, SLOT(slotEndOfGame()));
 
114
 
 
115
        qApp->processEvents();
 
116
 
 
117
        updateScore();
 
118
        enableItems();
 
119
}
 
120
 
 
121
void App::setupStatusBar()
 
122
{
 
123
        gameTipLabel= new QLabel(i18n("Select a tile"), statusBar());
 
124
        statusBar()->addWidget(gameTipLabel, 1);
 
125
        
 
126
        gameTimerLabel = new QLabel(i18n("Time: 0:00:00"), statusBar());
 
127
        statusBar()->addWidget(gameTimerLabel);
 
128
        
 
129
        gameTilesLabel = new QLabel(i18n("Removed: 0/0"), statusBar());
 
130
        statusBar()->addWidget(gameTilesLabel);
 
131
        
 
132
        gameCheatLabel = new QLabel(i18n("Cheat mode"), statusBar());
 
133
        statusBar()->addWidget(gameCheatLabel);
 
134
        gameCheatLabel->hide();
 
135
}
 
136
 
 
137
void App::setupActions()
 
138
{
 
139
        // Game
 
140
        KStandardGameAction::gameNew(this, SLOT(newGame()), actionCollection());
 
141
        KStandardGameAction::restart(this, SLOT(restartGame()), actionCollection());
 
142
        KStandardGameAction::pause(this, SLOT(pause()), actionCollection());
 
143
        KStandardGameAction::highscores(this, SLOT(hallOfFame()), actionCollection());
 
144
        KStandardGameAction::quit(this, SLOT(close()), actionCollection());
 
145
 
 
146
        // Move
 
147
        KStandardGameAction::undo(this, SLOT(undo()), actionCollection());
 
148
        KStandardGameAction::redo(this, SLOT(redo()), actionCollection());
 
149
        KStandardGameAction::hint(this, SLOT(hint()), actionCollection());
 
150
        //new KAction(i18n("Is Game Solvable?"), 0, this,
 
151
        //      SLOT(isSolvable()), actionCollection(), "move_solvable");
 
152
 
 
153
#ifdef DEBUGGING
 
154
        // broken ..
 
155
        //(void)new KAction(i18n("&Finish"), 0, board, SLOT(finish()), actionCollection(), "move_finish");
 
156
#endif
 
157
 
 
158
        // Settings
 
159
        KStandardAction::preferences(this, SLOT(showSettings()), actionCollection());
 
160
}
 
161
 
 
162
void App::hallOfFame()
 
163
{
 
164
        showHighscore();
 
165
}
 
166
 
 
167
void App::newGame()
 
168
{
 
169
        board->newGame();
 
170
        resetCheatMode();
 
171
        enableItems();
 
172
}
 
173
 
 
174
void App::restartGame()
 
175
{
 
176
        board->setUpdatesEnabled(false);
 
177
        while(board->canUndo())
 
178
                board->undo();
 
179
        board->setUpdatesEnabled(true);
 
180
        board->resetRedo();
 
181
        board->update();
 
182
        board->resetTimer();
 
183
        resetCheatMode();
 
184
        enableItems();
 
185
}
 
186
 
 
187
void App::isSolvable()
 
188
{
 
189
        if(board->solvable())
 
190
                KMessageBox::information(this, i18n("This game is solvable."));
 
191
        else
 
192
                KMessageBox::information(this, i18n("This game is NOT solvable."));
 
193
}
 
194
 
 
195
void App::pause()
 
196
{
 
197
        lockMenus(board->pause());
 
198
}
 
199
 
 
200
void App::undo()
 
201
{
 
202
        if(board->canUndo())
 
203
        {
 
204
                board->undo();
 
205
                setCheatMode();
 
206
                enableItems();
 
207
        }
 
208
}
 
209
 
 
210
void App::redo()
 
211
{
 
212
        if(board->canRedo())
 
213
                board->redo();
 
214
        enableItems();
 
215
}
 
216
 
 
217
void App::hint()
 
218
{
 
219
#ifdef DEBUGGING
 
220
        board->makeHintMove();
 
221
#else
 
222
        board->showHint();
 
223
        setCheatMode();
 
224
#endif
 
225
        enableItems();
 
226
}
 
227
 
 
228
void App::lockMenus(bool lock)
 
229
{
 
230
        // Disable all actions apart from (un)pause, quit and those that are help-related.
 
231
        // (Only undo/redo and hint actually *need* to be disabled, but disabling everything
 
232
        // provides a good visual hint to the user, that they need to unpause to continue.
 
233
        KMenu* help = findChild<KMenu*>("help" );
 
234
        QList<QAction*> actions = actionCollection()->actions();
 
235
        QList<QAction*>::const_iterator actionIter = actions.constBegin();
 
236
        QList<QAction*>::const_iterator actionIterEnd = actions.constEnd();
 
237
 
 
238
        while(actionIter != actionIterEnd)
 
239
        {
 
240
                QAction* a = *actionIter;
 
241
                if(!a->associatedWidgets().contains(help))
 
242
                        a->setEnabled(!lock);
 
243
                ++actionIter;
 
244
        }
 
245
 
 
246
        actionCollection()->action(KStandardGameAction::name(KStandardGameAction::Pause))->setEnabled(true);
 
247
        actionCollection()->action(KStandardGameAction::name(KStandardGameAction::Quit))->setEnabled(true);
 
248
 
 
249
        enableItems();
 
250
}
 
251
 
 
252
void App::enableItems()
 
253
{
 
254
        if(!board->isPaused())
 
255
        {
 
256
                actionCollection()->action(KStandardGameAction::name(KStandardGameAction::Undo))->setEnabled(board->canUndo());
 
257
                actionCollection()->action(KStandardGameAction::name(KStandardGameAction::Redo))->setEnabled(board->canRedo());
 
258
                actionCollection()->action(KStandardGameAction::name(KStandardGameAction::Restart))->setEnabled(board->canUndo());
 
259
        }
 
260
}
 
261
 
 
262
void App::slotEndOfGame()
 
263
{
 
264
        if(board->tilesLeft() > 0)
 
265
        {
 
266
                KMessageBox::information(this, i18n("No more moves possible!"), i18n("End of Game"));
 
267
        }
 
268
        else
 
269
        {
 
270
                // create highscore entry
 
271
                HighScore hs;
 
272
                hs.seconds = board->getTimeForGame();
 
273
                hs.x = board->x_tiles();
 
274
                hs.y = board->y_tiles();
 
275
                hs.gravity = (int)board->gravityFlag();
 
276
 
 
277
                // check if we made it into Top10
 
278
                bool isHighscore = false;
 
279
                if(highscore.size() < HIGHSCORE_MAX)
 
280
                        isHighscore = true;
 
281
                else if(isBetter(hs, highscore[HIGHSCORE_MAX-1]))
 
282
                        isHighscore = true;
 
283
 
 
284
                if(isHighscore && !cheat)
 
285
                {
 
286
                        hs.name = getPlayerName();
 
287
                        hs.date = time((time_t*)0);
 
288
                        int rank = insertHighscore(hs);
 
289
                        showHighscore(rank);
 
290
                }
 
291
                else
 
292
                {
 
293
                        QString s = i18n("Congratulations! You made it in %1:%2:%3",
 
294
                                 QString().sprintf("%02d", board->getTimeForGame()/3600),
 
295
                                 QString().sprintf("%02d", (board->getTimeForGame() / 60) % 60),
 
296
                                 QString().sprintf("%02d", board->getTimeForGame() % 60));
 
297
 
 
298
                        if(isHighscore) // player would have been in the hisghscores if he did not cheat
 
299
                        {
 
300
                                s += '\n' + i18n("You could have been in the highscores if you did not use Undo or Hint. Try without them next time.");
 
301
                        }
 
302
 
 
303
                        KMessageBox::information(this, s, i18n("End of Game"));
 
304
                }
 
305
        }
 
306
 
 
307
        resetCheatMode();
 
308
        board->newGame();
 
309
}
 
310
 
 
311
void App::notifySelectATile()
 
312
{
 
313
        gameTipLabel->setText(i18n("Select a tile"));
 
314
}
 
315
 
 
316
void App::notifySelectAMatchingTile()
 
317
{
 
318
        gameTipLabel->setText(i18n("Select a matching tile"));
 
319
}
 
320
 
 
321
void App::notifySelectAMove()
 
322
{
 
323
        gameTipLabel->setText(i18n("Select the move you want by clicking on the blue line"));
 
324
}
 
325
 
 
326
void App::notifyTilesDontMatch()
 
327
{
 
328
        gameTipLabel->setText(i18n("This tile did not match the one you selected"));
 
329
}
 
330
 
 
331
void App::notifyInvalidMove()
 
332
{
 
333
        gameTipLabel->setText(i18n("You cannot make this move"));
 
334
}
 
335
 
 
336
void App::updateScore()
 
337
{
 
338
        int t = board->getTimeForGame();
 
339
        QString s = i18n(" Your time: %1:%2:%3 %4",
 
340
                 QString().sprintf("%02d", t / 3600 ),
 
341
                 QString().sprintf("%02d", (t / 60) % 60 ),
 
342
                 QString().sprintf("%02d", t % 60 ),
 
343
                 board->isPaused()?i18n("(Paused) "):QString());
 
344
 
 
345
        //statusBar()->changeItem(s, SBI_TIME);
 
346
        gameTimerLabel->setText(s);
 
347
 
 
348
        // Number of tiles
 
349
        int tl = (board->x_tiles() * board->y_tiles());
 
350
        s = i18n(" Removed: %1/%2 ",
 
351
                 QString().sprintf("%d", tl - board->tilesLeft()),
 
352
                 QString().sprintf("%d", tl ));
 
353
 
 
354
        //statusBar()->changeItem(s, SBI_TILES);
 
355
        gameTilesLabel->setText(s);
 
356
}
 
357
 
 
358
void App::setCheatMode()
 
359
{
 
360
        // set the cheat mode if not set
 
361
        if(!cheat)
 
362
        {
 
363
                cheat = true;
 
364
                gameCheatLabel->show();
 
365
        }
 
366
}
 
367
 
 
368
void App::resetCheatMode()
 
369
{
 
370
        // reset cheat mode if set
 
371
        if(cheat)
 
372
        {
 
373
                cheat = false;
 
374
                gameCheatLabel->hide();
 
375
        }
 
376
}
 
377
 
 
378
QString App::getPlayerName()
 
379
{
 
380
        KDialog dlg(this);
 
381
        dlg.setObjectName( "Hall of Fame" );
 
382
        dlg.setButtons( KDialog::Ok );
 
383
 
 
384
        QWidget* dummy = new QWidget( &dlg );
 
385
        dlg.setMainWidget( dummy );
 
386
 
 
387
        QLabel *l1 = new QLabel(i18n("You have made it into the \"Hall Of Fame\". Type in\nyour name so mankind will always remember\nyour cool rating."), dummy);
 
388
 
 
389
        QLabel *l2 = new QLabel(i18n("Your name:"), dummy);
 
390
 
 
391
        KLineEdit *e = new KLineEdit( dummy );
 
392
        e->setMinimumWidth( e->fontMetrics().width( "XXXXXXXXXXXXXXXX" ) );
 
393
        e->setText( lastPlayerName );
 
394
        e->setFocus();
 
395
 
 
396
        // create layout
 
397
        QHBoxLayout *tl1 = new QHBoxLayout;
 
398
        tl1->addWidget(l2);
 
399
        tl1->addWidget(e);
 
400
        QVBoxLayout *tl = new QVBoxLayout( dummy );
 
401
        tl->setMargin( 10 );
 
402
        tl->setSpacing( 5 );
 
403
        tl->addWidget(l1);
 
404
        tl->addLayout(tl1);
 
405
 
 
406
        dlg.exec();
 
407
 
 
408
        lastPlayerName = e->text();
 
409
 
 
410
        if(lastPlayerName.isEmpty())
 
411
                return " ";
 
412
        return lastPlayerName;
 
413
}
 
414
 
 
415
int App::getScore(const HighScore &hs)
 
416
{
 
417
        double ntiles = hs.x*hs.y;
 
418
        double tilespersec = ntiles/(double)hs.seconds;
 
419
 
 
420
        double sizebonus = std::sqrt(ntiles/(double)(14.0 * 6.0));
 
421
        double points = tilespersec / 0.14 * 100.0;
 
422
 
 
423
        if(hs.gravity)
 
424
                return (int)(2.0 * points * sizebonus);
 
425
        else
 
426
                return (int)(points * sizebonus);
 
427
}
 
428
 
 
429
bool App::isBetter(const HighScore &hs, const HighScore &than)
 
430
{
 
431
        if(getScore(hs) > getScore(than))
 
432
                return true;
 
433
        else
 
434
                return false;
 
435
}
 
436
 
 
437
int App::insertHighscore(const HighScore &hs)
 
438
{
 
439
        int i;
 
440
 
 
441
        if(highscore.size() == 0)
 
442
        {
 
443
                highscore.resize(1);
 
444
                highscore[0] = hs;
 
445
                writeHighscore();
 
446
                return 0;
 
447
        }
 
448
        else
 
449
        {
 
450
                HighScore last = highscore[highscore.size() - 1];
 
451
                if(isBetter(hs, last) || (highscore.size() < HIGHSCORE_MAX))
 
452
                {
 
453
                        if(highscore.size() == HIGHSCORE_MAX)
 
454
                        {
 
455
                                highscore[HIGHSCORE_MAX - 1] = hs;
 
456
                        }
 
457
                        else
 
458
                        {
 
459
                                highscore.resize(highscore.size()+1);
 
460
                                highscore[highscore.size() - 1] = hs;
 
461
                        }
 
462
 
 
463
                        // sort in new entry
 
464
                        int bestsofar = highscore.size() - 1;
 
465
                        for(i = highscore.size() - 1; i > 0; i--)
 
466
                        {
 
467
                                if(isBetter(highscore[i], highscore[i-1]))
 
468
                                {
 
469
                                        // swap entries
 
470
                                        HighScore temp = highscore[i-1];
 
471
                                        highscore[i-1] = highscore[i];
 
472
                                        highscore[i] = temp;
 
473
                                        bestsofar = i - 1;
 
474
                                }
 
475
                        }
 
476
 
 
477
                        writeHighscore();
 
478
                        return bestsofar;
 
479
                }
 
480
        }
 
481
        return -1;
 
482
}
 
483
 
 
484
void App::readHighscore()
 
485
{
 
486
        QStringList hi_x, hi_y, hi_sec, hi_date, hi_grav, hi_name;
 
487
        hi_x = highscoreTable->readList("x", HIGHSCORE_MAX);
 
488
        hi_y = highscoreTable->readList("y", HIGHSCORE_MAX);
 
489
        hi_sec = highscoreTable->readList("seconds", HIGHSCORE_MAX);
 
490
        hi_date = highscoreTable->readList("date", HIGHSCORE_MAX);
 
491
        hi_grav = highscoreTable->readList("gravity", HIGHSCORE_MAX);
 
492
        hi_name = highscoreTable->readList("name", HIGHSCORE_MAX);
 
493
 
 
494
        highscore.resize(0);
 
495
 
 
496
        for (int i = 0; i < hi_x.count(); i++)
 
497
        {
 
498
                highscore.resize(i+1);
 
499
 
 
500
                HighScore hs;
 
501
 
 
502
                hs.x = hi_x[i].toInt();
 
503
                hs.y = hi_y[i].toInt();
 
504
                hs.seconds = hi_sec[i].toInt();
 
505
                hs.date = hi_date[i].toInt();
 
506
                hs.date = hi_date[i].toInt();
 
507
                hs.gravity = hi_grav[i].toInt();
 
508
                hs.name = hi_name[i];
 
509
 
 
510
                highscore[i] = hs;
 
511
        }
 
512
}
 
513
 
 
514
void App::readOldHighscore()
 
515
{
 
516
        // this is for before-KHighscore-highscores
 
517
        int i;
 
518
        QString s, e;
 
519
        KSharedConfig::Ptr conf = KGlobal::config();
 
520
 
 
521
        highscore.resize(0);
 
522
        i = 0;
 
523
        bool eol = false;
 
524
        KConfigGroup group = conf->group("Hall of Fame");
 
525
        while ((i < (int)HIGHSCORE_MAX) && !eol)
 
526
        {
 
527
                s.sprintf("Highscore_%d", i);
 
528
                if(group.hasKey(s))
 
529
                {
 
530
                        e = group.readEntry(s,QString());
 
531
                        highscore.resize(i+1);
 
532
 
 
533
                        HighScore hs;
 
534
 
 
535
                        QStringList e = group.readEntry(s, QString()).split(' ');
 
536
                        int nelem = e.count();
 
537
                        hs.x = e.at(0).toInt();
 
538
                        hs.y = e.at(1).toInt();
 
539
                        hs.seconds = e.at(2).toInt();
 
540
                        hs.date = e.at(3).toInt();
 
541
 
 
542
                        if(nelem == 4) // old version <= 1.1
 
543
                        {
 
544
                                hs.gravity = 0;
 
545
                                hs.name = e.at(4);
 
546
                        }
 
547
                        else
 
548
                        {
 
549
                                hs.gravity = e.at(4).toInt();
 
550
                                hs.name = e.at(5);
 
551
                        }
 
552
 
 
553
                        highscore[i] = hs;
 
554
                }
 
555
                else
 
556
                {
 
557
                        eol = true;
 
558
                }
 
559
                i++;
 
560
        }
 
561
 
 
562
//      // freshly installed, add my own highscore
 
563
//      if(highscore.size() == 0)
 
564
//      {
 
565
//              HighScore hs;
 
566
//              hs.x = 28;
 
567
//              hs.y = 16;
 
568
//              hs.seconds = 367;
 
569
//              hs.name = "Mario";
 
570
//              highscore.resize(1);
 
571
//              highscore[0] = hs;
 
572
//      }
 
573
 
 
574
        // write in new KHighscore format
 
575
        writeHighscore();
 
576
        // read form KHighscore format
 
577
        readHighscore();
 
578
}
 
579
 
 
580
void App::writeHighscore()
 
581
{
 
582
        int i;
 
583
        QStringList hi_x, hi_y, hi_sec, hi_date, hi_grav, hi_name;
 
584
        for(i = 0; i < (int)highscore.size(); i++)
 
585
        {
 
586
                HighScore hs = highscore[i];
 
587
                hi_x.append(QString::number(hs.x));
 
588
                hi_y.append(QString::number(hs.y));
 
589
                hi_sec.append(QString::number(hs.seconds));
 
590
                hi_date.append(QString::number(hs.date));
 
591
                hi_grav.append(QString::number(hs.gravity));
 
592
                hi_name.append(hs.name);
 
593
        }
 
594
        highscoreTable->writeList("x", hi_x);
 
595
        highscoreTable->writeList("y", hi_y);
 
596
        highscoreTable->writeList("seconds", hi_sec);
 
597
        highscoreTable->writeList("date", hi_date);
 
598
        highscoreTable->writeList("gravity", hi_grav);
 
599
        highscoreTable->writeList("name", hi_name);
 
600
        highscoreTable->writeAndUnlock();
 
601
}
 
602
 
 
603
void App::showHighscore(int focusitem)
 
604
{
 
605
        // this may look a little bit confusing...
 
606
        KDialog dlg;
 
607
        dlg.setObjectName( "hall_Of_fame" );
 
608
        dlg.setButtons( KDialog::Close );
 
609
        dlg.setWindowTitle(i18n("Hall of Fame"));
 
610
 
 
611
        QWidget* dummy = new QWidget(&dlg);
 
612
        dlg.setMainWidget(dummy);
 
613
 
 
614
        QVBoxLayout *tl = new QVBoxLayout(dummy);
 
615
        tl->setMargin( 10 );
 
616
 
 
617
        QLabel *l = new QLabel(i18n("Hall of Fame"), dummy);
 
618
        QFont f = font();
 
619
        f.setPointSize(24);
 
620
        f.setBold(true);
 
621
        l->setFont(f);
 
622
        l->setAlignment(Qt::AlignCenter);
 
623
        tl->addWidget(l);
 
624
 
 
625
        // insert highscores in a gridlayout
 
626
        QGridLayout *table = new QGridLayout;
 
627
        tl->setSpacing(5);
 
628
        tl->addLayout(table, 1);
 
629
 
 
630
        // add a separator line
 
631
        KSeparator *sep = new KSeparator(dummy);
 
632
        table->addWidget(sep, 1, 0, 1, 5);
 
633
 
 
634
        // add titles
 
635
        f = font();
 
636
        f.setBold(true);
 
637
        l = new QLabel(i18n("Rank"), dummy);
 
638
        l->setFont(f);
 
639
        table->addWidget(l, 0, 0);
 
640
        l = new QLabel(i18n("Name"), dummy);
 
641
        l->setFont(f);
 
642
        table->addWidget(l, 0, 1);
 
643
        l = new QLabel(i18n("Time"), dummy);
 
644
        l->setFont(f);
 
645
        table->addWidget(l, 0, 2);
 
646
        l = new QLabel(i18n("Size"), dummy);
 
647
        l->setFont(f);
 
648
        table->addWidget(l, 0, 3);
 
649
        l = new QLabel(i18n("Score"), dummy);
 
650
        l->setFont(f);
 
651
        table->addWidget(l, 0, 4);
 
652
 
 
653
        QString s;
 
654
        QLabel *e[10][5];
 
655
        signed i, j;
 
656
 
 
657
        for(i = 0; i < 10; i++)
 
658
        {
 
659
                HighScore hs;
 
660
                if(i < highscore.size())
 
661
                        hs = highscore[i];
 
662
 
 
663
                // insert rank
 
664
                s.sprintf("%d", i+1);
 
665
                e[i][0] = new QLabel(s, dummy);
 
666
 
 
667
                // insert name
 
668
                if(i < highscore.size())
 
669
                        e[i][1] = new QLabel(hs.name, dummy);
 
670
                else
 
671
                        e[i][1] = new QLabel("", dummy);
 
672
 
 
673
                // insert time
 
674
                QTime ti(0,0,0);
 
675
                if(i < highscore.size())
 
676
                {
 
677
                        ti = ti.addSecs(hs.seconds);
 
678
                        s.sprintf("%02d:%02d:%02d", ti.hour(), ti.minute(), ti.second());
 
679
                        e[i][2] = new QLabel(s, dummy);
 
680
                }
 
681
                else
 
682
                {
 
683
                        e[i][2] = new QLabel("", dummy);
 
684
                }
 
685
 
 
686
                // insert size
 
687
                if(i < highscore.size())
 
688
                        s.sprintf("%d x %d", hs.x, hs.y);
 
689
                else
 
690
                        s = "";
 
691
 
 
692
                e[i][3] = new QLabel(s, dummy);
 
693
 
 
694
                // insert score
 
695
                if(i < highscore.size())
 
696
                {
 
697
                        s = QString("%1 %2")
 
698
                            .arg(getScore(hs))
 
699
                            .arg(hs.gravity ? i18n("(gravity)") : QString(""));
 
700
                }
 
701
                else
 
702
                {
 
703
                        s = "";
 
704
                }
 
705
 
 
706
                e[i][4] = new QLabel(s, dummy);
 
707
                e[i][4]->setAlignment(Qt::AlignRight);
 
708
        }
 
709
 
 
710
        f = font();
 
711
        f.setBold(true);
 
712
        f.setItalic(true);
 
713
        for(i = 0; i < 10; i++)
 
714
        {
 
715
                for(j = 0; j < 5; j++)
 
716
                {
 
717
                        if((int)i == focusitem)
 
718
                                e[i][j]->setFont(f);
 
719
 
 
720
                        table->addWidget(e[i][j], i+2, j, Qt::AlignCenter);
 
721
                }
 
722
        }
 
723
 
 
724
        dlg.exec();
 
725
}
 
726
 
 
727
void App::keyBindings()
 
728
{
 
729
        KShortcutsDialog::configure( actionCollection(), KShortcutsEditor::LetterShortcutsAllowed, this );
 
730
 
 
731
}
 
732
 
 
733
/**
 
734
 * Show Settings dialog.
 
735
 */
 
736
void App::showSettings(){
 
737
        if(KConfigDialog::showDialog("settings"))
 
738
                return;
 
739
 
 
740
        //Use the classes exposed by LibKmahjongg for our configuration dialog
 
741
        KMahjonggConfigDialog *dialog = new KMahjonggConfigDialog(this, "settings", Prefs::self());
 
742
        dialog->addPage(new Settings(0), i18n("General"), "games-config-options");
 
743
        dialog->addTilesetPage();
 
744
        dialog->addBackgroundPage();
 
745
        dialog->setHelp(QString(),"kshisen");
 
746
        connect(dialog, SIGNAL(settingsChanged(const QString &)), board, SLOT(loadSettings()));
 
747
        dialog->show();
 
748
}
 
749
 
 
750
#include "app.moc"