00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kexthighscore_item.h"
00021
00022 #include <qlayout.h>
00023 #include <kglobal.h>
00024 #include <kdialogbase.h>
00025 #include <kdebug.h>
00026
00027 #include "khighscore.h"
00028 #include "kexthighscore_internal.h"
00029 #include "kexthighscore_gui.h"
00030
00031
00032 namespace KExtHighscore
00033 {
00034
00035
00036 Item::Item(const QVariant &def, const QString &label, int alignment)
00037 : _default(def), _label(label), _alignment(alignment),
00038 _format(NoFormat), _special(NoSpecial)
00039 {}
00040
00041 Item::~Item()
00042 {}
00043
00044 QVariant Item::read(uint, const QVariant &value) const
00045 {
00046 return value;
00047 }
00048
00049 void Item::setPrettyFormat(Format format)
00050 {
00051 bool buint = ( _default.type()==QVariant::UInt );
00052 bool bdouble = ( _default.type()==QVariant::Double );
00053 bool bnum = ( buint || bdouble || _default.type()==QVariant::Int );
00054
00055 switch (format) {
00056 case OneDecimal:
00057 case Percentage:
00058 Q_ASSERT(bdouble);
00059 break;
00060 case MinuteTime:
00061 Q_ASSERT(bnum);
00062 break;
00063 case DateTime:
00064 Q_ASSERT( _default.type()==QVariant::DateTime );
00065 break;
00066 case NoFormat:
00067 break;
00068 }
00069
00070 _format = format;
00071 }
00072
00073 void Item::setPrettySpecial(Special special)
00074 {
00075 bool buint = ( _default.type()==QVariant::UInt );
00076 bool bnum = ( buint || _default.type()==QVariant::Double
00077 || _default.type()==QVariant::Int );
00078
00079 switch (special) {
00080 case ZeroNotDefined:
00081 Q_ASSERT(bnum);
00082 break;
00083 case NegativeNotDefined:
00084 Q_ASSERT(bnum && !buint);
00085 break;
00086 case DefaultNotDefined:
00087 break;
00088 case Anonymous:
00089 Q_ASSERT( _default.type()==QVariant::String );
00090 break;
00091 case NoSpecial:
00092 break;
00093 }
00094
00095 _special = special;
00096 }
00097
00098 QString Item::timeFormat(uint n)
00099 {
00100 Q_ASSERT( n<=3600 && n!=0 );
00101 n = 3600 - n;
00102 return QString::number(n / 60).rightJustify(2, '0') + ':'
00103 + QString::number(n % 60).rightJustify(2, '0');
00104 }
00105
00106 QString Item::pretty(uint, const QVariant &value) const
00107 {
00108 switch (_special) {
00109 case ZeroNotDefined:
00110 if ( value.toUInt()==0 ) return "--";
00111 break;
00112 case NegativeNotDefined:
00113 if ( value.toInt()<0 ) return "--";
00114 break;
00115 case DefaultNotDefined:
00116 if ( value==_default ) return "--";
00117 break;
00118 case Anonymous:
00119 if ( value.toString()==ItemContainer::ANONYMOUS )
00120 return i18n(ItemContainer::ANONYMOUS_LABEL);
00121 break;
00122 case NoFormat:
00123 break;
00124 }
00125
00126 switch (_format) {
00127 case OneDecimal:
00128 return QString::number(value.toDouble(), 'f', 1);
00129 case Percentage:
00130 return QString::number(value.toDouble(), 'f', 1) + "%";
00131 case MinuteTime:
00132 return timeFormat(value.toUInt());
00133 case DateTime:
00134 if ( value.toDateTime().isNull() ) return "--";
00135 return KGlobal::locale()->formatDateTime(value.toDateTime());
00136 case NoSpecial:
00137 break;
00138 }
00139
00140 return value.toString();
00141 }
00142
00143
00144 Score::Score(ScoreType type)
00145 : _type(type)
00146 {
00147 const ItemArray &items = internal->scoreInfos();
00148 for (uint i=0; i<items.size(); i++)
00149 _data[items[i]->name()] = items[i]->item()->defaultValue();
00150 }
00151
00152 Score::~Score()
00153 {}
00154
00155 const QVariant &Score::data(const QString &name) const
00156 {
00157 Q_ASSERT( _data.contains(name) );
00158 return _data[name];
00159 }
00160
00161 void Score::setData(const QString &name, const QVariant &value)
00162 {
00163 Q_ASSERT( _data.contains(name) );
00164 Q_ASSERT( _data[name].type()==value.type() );
00165 _data[name] = value;
00166 }
00167
00168 bool Score::isTheWorst() const
00169 {
00170 Score s;
00171 return score()==s.score();
00172 }
00173
00174 bool Score::operator <(const Score &score)
00175 {
00176 return internal->manager.isStrictlyLess(*this, score);
00177 }
00178
00179 QDataStream &operator <<(QDataStream &s, const Score &score)
00180 {
00181 s << (Q_UINT8)score.type();
00182 s << score._data;
00183 return s;
00184 }
00185
00186 QDataStream &operator >>(QDataStream &s, Score &score)
00187 {
00188 Q_UINT8 type;
00189 s >> type;
00190 score._type = (ScoreType)type;
00191 s >> score._data;
00192 return s;
00193 }
00194
00195
00196 MultiplayerScores::MultiplayerScores()
00197 {}
00198
00199 MultiplayerScores::~MultiplayerScores()
00200 {}
00201
00202 void MultiplayerScores::clear()
00203 {
00204 Score score;
00205 for (uint i=0; i<_scores.size(); i++) {
00206 _nbGames[i] = 0;
00207 QVariant name = _scores[i].data("name");
00208 _scores[i] = score;
00209 _scores[i].setData("name", name);
00210 _scores[i]._data["mean score"] = double(0);
00211 _scores[i]._data["nb won games"] = uint(0);
00212 }
00213 }
00214
00215 void MultiplayerScores::setPlayerCount(uint nb)
00216 {
00217 _nbGames.resize(nb);
00218 _scores.resize(nb);
00219 clear();
00220 }
00221
00222 void MultiplayerScores::setName(uint i, const QString &name)
00223 {
00224 _scores[i].setData("name", name);
00225 }
00226
00227 void MultiplayerScores::addScore(uint i, const Score &score)
00228 {
00229 QVariant name = _scores[i].data("name");
00230 double mean = _scores[i].data("mean score").toDouble();
00231 uint won = _scores[i].data("nb won games").toUInt();
00232 _scores[i] = score;
00233 _scores[i].setData("name", name);
00234 _nbGames[i]++;
00235 mean += (double(score.score()) - mean) / _nbGames[i];
00236 _scores[i]._data["mean score"] = mean;
00237 if ( score.type()==Won ) won++;
00238 _scores[i]._data["nb won games"] = won;
00239 }
00240
00241 void MultiplayerScores::show(QWidget *parent)
00242 {
00243
00244 if ( _nbGames.size()<2 ) kdWarning(11002) << "less than 2 players" << endl;
00245 else {
00246 bool ok = true;
00247 uint nb = _nbGames[0];
00248 for (uint i=1; i<_nbGames.size(); i++)
00249 if ( _nbGames[i]!=nb ) ok = false;
00250 if (!ok)
00251 kdWarning(11002) << "players have not same number of games" << endl;
00252 }
00253
00254
00255 QValueVector<Score> ordered;
00256 for (uint i=0; i<_scores.size(); i++) {
00257 uint won = _scores[i].data("nb won games").toUInt();
00258 double mean = _scores[i].data("mean score").toDouble();
00259 QValueVector<Score>::iterator it;
00260 for(it = ordered.begin(); it!=ordered.end(); ++it) {
00261 uint cwon = (*it).data("nb won games").toUInt();
00262 double cmean = (*it).data("mean score").toDouble();
00263 if ( won<cwon || (won==cwon && mean<cmean) ) {
00264 ordered.insert(it, _scores[i]);
00265 break;
00266 }
00267 }
00268 if ( it==ordered.end() ) ordered.push_back(_scores[i]);
00269 }
00270
00271
00272 KDialogBase dialog(KDialogBase::Plain, i18n("Multiplayers Scores"),
00273 KDialogBase::Close, KDialogBase::Close,
00274 parent, "show_multiplayers_score", true, true);
00275 QHBoxLayout *hbox = new QHBoxLayout(dialog.plainPage(),
00276 KDialog::marginHint(), KDialog::spacingHint());
00277
00278 QVBox *vbox = new QVBox(dialog.plainPage());
00279 hbox->addWidget(vbox);
00280 if ( _nbGames[0]==0 ) (void)new QLabel(i18n("No game played."), vbox);
00281 else {
00282 (void)new QLabel(i18n("Scores for last game:"), vbox);
00283 (void)new LastMultipleScoresList(ordered, vbox);
00284 }
00285
00286 if ( _nbGames[0]>1 ) {
00287 vbox = new QVBox(dialog.plainPage());
00288 hbox->addWidget(vbox);
00289 (void)new QLabel(i18n("Scores for the last %1 games:")
00290 .arg(_nbGames[0]), vbox);
00291 (void)new TotalMultipleScoresList(ordered, vbox);
00292 }
00293
00294 dialog.enableButtonSeparator(false);
00295 dialog.exec();
00296 }
00297
00298 QDataStream &operator <<(QDataStream &s, const MultiplayerScores &score)
00299 {
00300 s << score._scores;
00301 s << score._nbGames;
00302 return s;
00303 }
00304
00305 QDataStream &operator >>(QDataStream &s, MultiplayerScores &score)
00306 {
00307 s >> score._scores;
00308 s >> score._nbGames;
00309 return s;
00310 }
00311
00312 }