kscoredialog.cpp
00001 /**************************************************************** 00002 Copyright (c) 1998 Sandro Sigala <ssigala@globalnet.it>. 00003 Copyright (c) 2001 Waldo Bastian <bastian@kde.org> 00004 All rights reserved. 00005 00006 Permission to use, copy, modify, and distribute this software 00007 and its documentation for any purpose and without fee is hereby 00008 granted, provided that the above copyright notice appear in all 00009 copies and that both that the copyright notice and this 00010 permission notice and warranty disclaimer appear in supporting 00011 documentation, and that the name of the author not be used in 00012 advertising or publicity pertaining to distribution of the 00013 software without specific, written prior permission. 00014 00015 The author disclaim all warranties with regard to this 00016 software, including all implied warranties of merchantability 00017 and fitness. In no event shall the author be liable for any 00018 special, indirect or consequential damages or any damages 00019 whatsoever resulting from loss of use, data or profits, whether 00020 in an action of contract, negligence or other tortious action, 00021 arising out of or in connection with the use or performance of 00022 this software. 00023 ****************************************************************/ 00024 00025 #include "config.h" 00026 00027 #include <tqlabel.h> 00028 #include <tqlayout.h> 00029 #include <tqlineedit.h> 00030 #include <tqwidgetstack.h> 00031 #include <tqtimer.h> 00032 #include <tqevent.h> 00033 #include <tqptrvector.h> 00034 00035 #include <tdeapplication.h> 00036 #include <tdeconfig.h> 00037 #include <tdelocale.h> 00038 #include <kseparator.h> 00039 00040 #include "kscoredialog.h" 00041 00042 class KScoreDialog::KScoreDialogPrivate 00043 { 00044 public: 00045 TQPtrList<FieldInfo> scores; 00046 TQWidget *page; 00047 TQGridLayout *layout; 00048 TQLineEdit *edit; 00049 TQPtrVector<TQWidgetStack> stack; 00050 TQPtrVector<TQLabel> labels; 00051 TQLabel *commentLabel; 00052 TQString comment; 00053 int fields; 00054 int newName; 00055 int latest; 00056 int nrCols; 00057 bool loaded; 00058 TQString configGroup; 00059 00060 TQMap<int, int> col; 00061 TQMap<int, TQString> header; 00062 TQMap<int, TQString> key; 00063 TQString player; 00064 }; 00065 00066 00067 KScoreDialog::KScoreDialog(int fields, TQWidget *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, TQT_SIGNAL(okClicked()), TQT_SLOT(slotGotName())); 00094 } 00095 00096 KScoreDialog::~KScoreDialog() 00097 { 00098 delete d; 00099 } 00100 00101 void KScoreDialog::setConfigGroup(const TQString &group) 00102 { 00103 d->configGroup = group; 00104 d->loaded = false; 00105 } 00106 00107 void KScoreDialog::setComment(const TQString &comment) 00108 { 00109 d->comment = comment; 00110 } 00111 00112 void KScoreDialog::addField(int field, const TQString &header, const TQString &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 TQGridLayout(d->page, 15, d->nrCols, marginHint() + 20, spacingHint()); 00130 d->layout->addRowSpacing(4, 15); 00131 00132 d->commentLabel = new TQLabel(d->page); 00133 d->commentLabel->setAlignment(AlignVCenter | AlignHCenter); 00134 d->layout->addMultiCellWidget(d->commentLabel, 1, 1, 0, d->nrCols-1); 00135 00136 TQFont bold = font(); 00137 bold.setBold(true); 00138 00139 TQLabel *label; 00140 d->layout->addColSpacing(0, 50); 00141 label = new TQLabel(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 TQLabel(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(Qt::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 TQString num; 00164 for (int i = 1; i <= 10; ++i) { 00165 TQLabel *label; 00166 num.setNum(i); 00167 label = new TQLabel(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 TQWidgetStack *stack = new TQWidgetStack(d->page); 00173 d->stack.insert(i-1, stack); 00174 d->layout->addWidget(stack, i+4, d->col[Name]); 00175 label = new TQLabel(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 TQLabel(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(TQSize(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 = TQString(); 00216 00217 TQFont normal = font(); 00218 TQFont bold = normal; 00219 bold.setBold(true); 00220 00221 TQString num; 00222 for (int i = 1; i <= 10; ++i) { 00223 TQLabel *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 TQWidgetStack *stack = d->stack[i-1]; 00237 d->edit = new TQLineEdit(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, TQT_SIGNAL(returnPressed()), 00243 this, TQT_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 TQString key, value; 00276 d->loaded = true; 00277 d->scores.clear(); 00278 TDEConfigGroup config(kapp->config(), d->configGroup.utf8()); 00279 00280 d->player = config.readEntry("LastPlayer"); 00281 00282 TQString 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 TQString key, value; 00301 TDEConfigGroup config(kapp->config(), d->configGroup.utf8()); 00302 00303 config.writeEntry("LastPlayer", d->player); 00304 00305 TQString 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 TQTimer::singleShot(0, this, TQT_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 TQFont bold = font(); 00381 bold.setBold(true); 00382 00383 TQLabel *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( TQKeyEvent *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"