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