00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026
00027 #include <qlabel.h>
00028 #include <qlayout.h>
00029 #include <qlineedit.h>
00030 #include <qwidgetstack.h>
00031 #include <qtimer.h>
00032 #include <qevent.h>
00033 #include <qptrvector.h>
00034
00035 #include <kapplication.h>
00036 #include <kconfig.h>
00037 #include <klocale.h>
00038 #include <kseparator.h>
00039
00040 #include "kscoredialog.h"
00041
00042 class KScoreDialog::KScoreDialogPrivate
00043 {
00044 public:
00045 QPtrList<FieldInfo> scores;
00046 QWidget *page;
00047 QGridLayout *layout;
00048 QLineEdit *edit;
00049 QPtrVector<QWidgetStack> stack;
00050 QPtrVector<QLabel> labels;
00051 QLabel *commentLabel;
00052 QString comment;
00053 int fields;
00054 int newName;
00055 int latest;
00056 int nrCols;
00057 bool loaded;
00058 QString configGroup;
00059
00060 QMap<int, int> col;
00061 QMap<int, QString> header;
00062 QMap<int, QString> key;
00063 QString player;
00064 };
00065
00066
00067 KScoreDialog::KScoreDialog(int fields, QWidget *parent, const char *oname)
00068 : KDialogBase(parent, oname, true, i18n("High Scores"), Ok, Ok, true)
00069 {
00070 d = new KScoreDialogPrivate();
00071 d->edit = 0;
00072 d->fields = fields;
00073 d->newName = -1;
00074 d->latest = -1;
00075 d->loaded = false;
00076 d->nrCols = 0;
00077 d->configGroup = "High Score";
00078
00079 d->scores.setAutoDelete(true);
00080 d->header[Name] = i18n("Name");
00081 d->key[Name] = "Name";
00082
00083 d->header[Level] = i18n("Level");
00084 d->key[Level] = "Level";
00085
00086 d->header[Score] = i18n("Score");
00087 d->key[Score] = "Score";
00088 d->page = makeMainWidget();
00089
00090 connect(this, SIGNAL(okClicked()), SLOT(slotGotName()));
00091 }
00092
00093 KScoreDialog::~KScoreDialog()
00094 {
00095 delete d;
00096 }
00097
00098 void KScoreDialog::setConfigGroup(const QString &group)
00099 {
00100 d->configGroup = group;
00101 d->loaded = false;
00102 }
00103
00104 void KScoreDialog::setComment(const QString &comment)
00105 {
00106 d->comment = comment;
00107 }
00108
00109 void KScoreDialog::addField(int field, const QString &header, const QString &key)
00110 {
00111 d->fields |= field;
00112 d->header[field] = header;
00113 d->key[field] = key;
00114 }
00115
00116 void KScoreDialog::setupDialog()
00117 {
00118 d->nrCols = 1;
00119
00120 for(int field = 1; field < d->fields; field = field * 2)
00121 {
00122 if (d->fields & field)
00123 d->col[field] = d->nrCols++;
00124 }
00125
00126 d->layout = new QGridLayout(d->page, 15, d->nrCols, marginHint() + 20, spacingHint());
00127 d->layout->addRowSpacing(4, 15);
00128
00129 d->commentLabel = new QLabel(d->page);
00130 d->commentLabel->setAlignment(AlignVCenter | AlignHCenter);
00131 d->layout->addMultiCellWidget(d->commentLabel, 1, 1, 0, d->nrCols-1);
00132
00133 QFont bold = font();
00134 bold.setBold(true);
00135
00136 QLabel *label;
00137 d->layout->addColSpacing(0, 50);
00138 label = new QLabel(i18n("Rank"), d->page);
00139 d->layout->addWidget(label, 3, 0);
00140 label->setFont(bold);
00141
00142 for(int field = 1; field < d->fields; field = field * 2)
00143 {
00144 if (d->fields & field)
00145 {
00146 d->layout->addColSpacing(d->col[field], 50);
00147
00148 label = new QLabel(d->header[field], d->page);
00149 d->layout->addWidget(label, 3, d->col[field], field <= Name ? AlignLeft : AlignRight);
00150 label->setFont(bold);
00151 }
00152 }
00153
00154 KSeparator *sep = new KSeparator(Horizontal, d->page);
00155 d->layout->addMultiCellWidget(sep, 4, 4, 0, d->nrCols-1);
00156
00157 d->labels.resize(d->nrCols * 10);
00158 d->stack.resize(10);
00159
00160 QString num;
00161 for (int i = 1; i <= 10; ++i) {
00162 QLabel *label;
00163 num.setNum(i);
00164 label = new QLabel("#"+num, d->page);
00165 d->labels.insert((i-1)*d->nrCols + 0, label);
00166 d->layout->addWidget(label, i+4, 0);
00167 if (d->fields & Name)
00168 {
00169 QWidgetStack *stack = new QWidgetStack(d->page);
00170 d->stack.insert(i-1, stack);
00171 d->layout->addWidget(stack, i+4, d->col[Name]);
00172 label = new QLabel(d->page);
00173 d->labels.insert((i-1)*d->nrCols + d->col[Name], label);
00174 stack->addWidget(label);
00175 stack->raiseWidget(label);
00176 }
00177 for(int field = Name * 2; field < d->fields; field = field * 2)
00178 {
00179 if (d->fields & field)
00180 {
00181 label = new QLabel(d->page);
00182 d->labels.insert((i-1)*d->nrCols + d->col[field], label);
00183 d->layout->addWidget(label, i+4, d->col[field], AlignRight);
00184 }
00185 }
00186 }
00187 }
00188
00189 void KScoreDialog::aboutToShow()
00190 {
00191 if (!d->loaded)
00192 loadScores();
00193
00194 if (!d->nrCols)
00195 setupDialog();
00196
00197 d->commentLabel->setText(d->comment);
00198 if (d->comment.isEmpty())
00199 {
00200 d->commentLabel->setMinimumSize(QSize(1,1));
00201 d->commentLabel->hide();
00202 d->layout->addRowSpacing(0, -15);
00203 d->layout->addRowSpacing(2, -15);
00204 }
00205 else
00206 {
00207 d->commentLabel->setMinimumSize(d->commentLabel->sizeHint());
00208 d->commentLabel->show();
00209 d->layout->addRowSpacing(0, -10);
00210 d->layout->addRowSpacing(2, 10);
00211 }
00212 d->comment = QString::null;
00213
00214 QFont normal = font();
00215 QFont bold = normal;
00216 bold.setBold(true);
00217
00218 QString num;
00219 for (int i = 1; i <= 10; ++i) {
00220 QLabel *label;
00221 num.setNum(i);
00222 FieldInfo *score = d->scores.at(i-1);
00223 label = d->labels[(i-1)*d->nrCols + 0];
00224 if (i == d->latest)
00225 label->setFont(bold);
00226 else
00227 label->setFont(normal);
00228
00229 if (d->fields & Name)
00230 {
00231 if (d->newName == i)
00232 {
00233 QWidgetStack *stack = d->stack[i-1];
00234 d->edit = new QLineEdit(d->player, stack);
00235 d->edit->setMinimumWidth(40);
00236 stack->addWidget(d->edit);
00237 stack->raiseWidget(d->edit);
00238 d->edit->setFocus();
00239 connect(d->edit, SIGNAL(returnPressed()),
00240 this, SLOT(slotGotReturn()));
00241 }
00242 else
00243 {
00244 label = d->labels[(i-1)*d->nrCols + d->col[Name]];
00245 if (i == d->latest)
00246 label->setFont(bold);
00247 else
00248 label->setFont(normal);
00249 label->setText((*score)[Name]);
00250 }
00251
00252 }
00253 for(int field = Name * 2; field < d->fields; field = field * 2)
00254 {
00255 if (d->fields & field)
00256 {
00257 label = d->labels[(i-1)*d->nrCols + d->col[field]];
00258 if (i == d->latest)
00259 label->setFont(bold);
00260 else
00261 label->setFont(normal);
00262 label->setText((*score)[field]);
00263 }
00264 }
00265 }
00266 d->latest = -1;
00267 setFixedSize(minimumSizeHint());
00268 }
00269
00270 void KScoreDialog::loadScores()
00271 {
00272 QString key, value;
00273 d->loaded = true;
00274 d->scores.clear();
00275 KConfigGroup config(kapp->config(), d->configGroup.utf8());
00276
00277 d->player = config.readEntry("LastPlayer");
00278
00279 QString num;
00280 for (int i = 1; i <= 10; ++i) {
00281 num.setNum(i);
00282 FieldInfo *score = new FieldInfo();
00283 for(int field = 1; field < d->fields; field = field * 2)
00284 {
00285 if (d->fields & field)
00286 {
00287 key = "Pos" + num + d->key[field];
00288 (*score)[field] = config.readEntry(key, "-");
00289 }
00290 }
00291 d->scores.append(score);
00292 }
00293 }
00294
00295 void KScoreDialog::saveScores()
00296 {
00297 QString key, value;
00298 KConfigGroup config(kapp->config(), d->configGroup.utf8());
00299
00300 config.writeEntry("LastPlayer", d->player);
00301
00302 QString num;
00303 for (int i = 1; i <= 10; ++i) {
00304 num.setNum(i);
00305 FieldInfo *score = d->scores.at(i-1);
00306 for(int field = 1; field < d->fields; field = field * 2)
00307 {
00308 if (d->fields & field)
00309 {
00310 key = "Pos" + num + d->key[field];
00311 config.writeEntry(key, (*score)[field]);
00312 }
00313 }
00314 }
00315 kapp->config()->sync();
00316 }
00317
00318 int KScoreDialog::addScore(int newScore, const FieldInfo &newInfo, bool askName)
00319 {
00320 return addScore(newScore, newInfo, askName, false);
00321 }
00322
00323 int KScoreDialog::addScore(int newScore, const FieldInfo &newInfo, bool askName, bool lessIsMore)
00324 {
00325 if (!d->loaded)
00326 loadScores();
00327 FieldInfo *score = d->scores.first();
00328 int i = 1;
00329 for(; score; score = d->scores.next(), i++)
00330 {
00331 bool ok;
00332 int num_score = (*score)[Score].toLong(&ok);
00333 if (lessIsMore && !ok)
00334 num_score = 1 << 30;
00335 if (((newScore > num_score) && !lessIsMore) ||
00336 ((newScore < num_score) && lessIsMore))
00337 {
00338 score = new FieldInfo(newInfo);
00339 (*score)[Score].setNum(newScore);
00340 d->scores.insert(i-1, score);
00341 d->scores.remove(10);
00342 d->latest = i;
00343 if (askName)
00344 d->newName = i;
00345 else
00346 saveScores();
00347 if (i == 1)
00348 d->comment = i18n("Excellent!\nYou have a new high score!");
00349 else
00350 d->comment = i18n("Well done!\nYou made it to the high score list!");
00351 return i;
00352 }
00353 }
00354 return 0;
00355 }
00356
00357 void KScoreDialog::show()
00358 {
00359 aboutToShow();
00360 KDialogBase::show();
00361 }
00362
00363 void KScoreDialog::slotGotReturn()
00364 {
00365 QTimer::singleShot(0, this, SLOT(slotGotName()));
00366 }
00367
00368 void KScoreDialog::slotGotName()
00369 {
00370 if (d->newName == -1) return;
00371
00372 d->player = d->edit->text();
00373
00374 (*d->scores.at(d->newName-1))[Name] = d->player;
00375 saveScores();
00376
00377 QFont bold = font();
00378 bold.setBold(true);
00379
00380 QLabel *label = d->labels[(d->newName-1)*d->nrCols + d->col[Name]];
00381 label->setFont(bold);
00382 label->setText(d->player);
00383 d->stack[(d->newName-1)]->raiseWidget(label);
00384 delete d->edit;
00385 d->edit = 0;
00386 d->newName = -1;
00387 }
00388
00389 int KScoreDialog::highScore()
00390 {
00391 if (!d->loaded)
00392 loadScores();
00393
00394 return (*d->scores.first())[Score].toInt();
00395 }
00396
00397 void KScoreDialog::keyPressEvent( QKeyEvent *ev)
00398 {
00399 if ((d->newName != -1) && (ev->key() == Key_Return))
00400 {
00401 ev->ignore();
00402 return;
00403 }
00404 KDialogBase::keyPressEvent(ev);
00405 }
00406
00407
00408 #include "kscoredialog.moc"