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 <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"
KDE Home | KDE Accessibility Home | Description of Access Keys