Warning, file /games/kreversi/src/kexthighscore_item.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2001-2003 Nicolas Hadacek <hadacek@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-only 0005 */ 0006 0007 #include "kexthighscore_item.h" 0008 0009 #include <QApplication> 0010 #include <QHBoxLayout> 0011 #include <QLabel> 0012 #include <QLocale> 0013 #include <QWidget> 0014 0015 #include <KPageDialog> 0016 0017 #include <KGameHighscore> 0018 0019 #include "kexthighscore_internal.h" 0020 #include "kexthighscore_gui.h" 0021 0022 0023 namespace KExtHighscore 0024 { 0025 0026 //----------------------------------------------------------------------------- 0027 Item::Item(const QVariant &def, const QString &label, Qt::AlignmentFlag alignment) 0028 : _default(def), _label(label), _alignment(alignment), 0029 _format(NoFormat), _special(NoSpecial) 0030 {} 0031 0032 Item::~Item() 0033 {} 0034 0035 QVariant Item::read(uint, const QVariant &value) const 0036 { 0037 return value; 0038 } 0039 0040 void Item::setPrettyFormat(Format format) 0041 { 0042 bool buint = (_default.metaType().id() == QMetaType::UInt); 0043 bool bdouble = (_default.metaType().id() == QMetaType::Double); 0044 bool bnum = (buint || bdouble || _default.metaType().id() == QMetaType::Int); 0045 0046 switch (format) { 0047 case OneDecimal: 0048 case Percentage: 0049 Q_ASSERT(bdouble); 0050 break; 0051 case MinuteTime: 0052 Q_ASSERT(bnum); 0053 break; 0054 case DateTime: 0055 Q_ASSERT(_default.metaType().id() == QMetaType::QDateTime); 0056 break; 0057 case NoFormat: 0058 break; 0059 } 0060 0061 _format = format; 0062 } 0063 0064 void Item::setPrettySpecial(Special special) 0065 { 0066 bool buint = (_default.metaType().id() == QMetaType::UInt); 0067 bool bnum = (buint || _default.metaType().id() == QMetaType::Double 0068 || _default.metaType().id() == QMetaType::Int); 0069 0070 switch (special) { 0071 case ZeroNotDefined: 0072 Q_ASSERT(bnum); 0073 break; 0074 case NegativeNotDefined: 0075 Q_ASSERT(bnum && !buint); 0076 break; 0077 case DefaultNotDefined: 0078 break; 0079 case Anonymous: 0080 Q_ASSERT(_default.metaType().id() == QMetaType::QString); 0081 break; 0082 case NoSpecial: 0083 break; 0084 } 0085 0086 _special = special; 0087 } 0088 0089 QString Item::timeFormat(uint n) 0090 { 0091 Q_ASSERT( n<=3600 && n!=0 ); 0092 n = 3600 - n; 0093 return QString::number(n / 60).rightJustified(2, QLatin1Char( '0' )) + QLatin1Char( ':' ) 0094 + QString::number(n % 60).rightJustified(2, QLatin1Char( '0' )); 0095 } 0096 0097 QString Item::pretty(uint, const QVariant &value) const 0098 { 0099 switch (_special) { 0100 case ZeroNotDefined: 0101 if ( value.toUInt()==0 ) return QStringLiteral( "--" ); 0102 break; 0103 case NegativeNotDefined: 0104 if ( value.toInt()<0 ) return QStringLiteral( "--" ); 0105 break; 0106 case DefaultNotDefined: 0107 if ( value==_default ) return QStringLiteral( "--" ); 0108 break; 0109 case Anonymous: 0110 if ( value.toString()==QLatin1String( ItemContainer::ANONYMOUS ) ) 0111 return ItemContainer::ANONYMOUS_LABEL.toString(); 0112 break; 0113 case NoSpecial: 0114 break; 0115 } 0116 0117 switch (_format) { 0118 case OneDecimal: 0119 return QString::number(value.toDouble(), 'f', 1); 0120 case Percentage: 0121 return QString::number(value.toDouble(), 'f', 1) + QLatin1Char( '%' ); 0122 case MinuteTime: 0123 return timeFormat(value.toUInt()); 0124 case DateTime: 0125 if ( value.toDateTime().isNull() ) return QStringLiteral( "--" ); 0126 return QLocale().toString(value.toDateTime()); 0127 case NoFormat: 0128 break; 0129 } 0130 0131 return value.toString(); 0132 } 0133 0134 //----------------------------------------------------------------------------- 0135 Score::Score(ScoreType type) 0136 : _type(type) 0137 { 0138 const ItemArray &items = internal->scoreInfos(); 0139 for (int i=0; i<items.size(); i++) 0140 _data[items[i]->name()] = items[i]->item()->defaultValue(); 0141 } 0142 0143 Score::~Score() 0144 {} 0145 0146 QVariant Score::data(const QString &name) const 0147 { 0148 Q_ASSERT( _data.contains(name) ); 0149 return _data[name]; 0150 } 0151 0152 void Score::setData(const QString &name, const QVariant &value) 0153 { 0154 Q_ASSERT( _data.contains(name) ); 0155 Q_ASSERT(_data[name].metaType() == value.metaType()); 0156 _data[name] = value; 0157 } 0158 0159 bool Score::isTheWorst() const 0160 { 0161 Score s; 0162 return score()==s.score(); 0163 } 0164 0165 bool Score::operator <(const Score &score) const 0166 { 0167 return internal->manager.isStrictlyLess(*this, score); 0168 } 0169 0170 QDataStream &operator <<(QDataStream &s, const Score &score) 0171 { 0172 s << (quint8)score.type(); 0173 s << score._data; 0174 return s; 0175 } 0176 0177 QDataStream &operator >>(QDataStream &s, Score &score) 0178 { 0179 quint8 type; 0180 s >> type; 0181 score._type = (ScoreType)type; 0182 s >> score._data; 0183 return s; 0184 } 0185 0186 //----------------------------------------------------------------------------- 0187 MultiplayerScores::MultiplayerScores() 0188 {} 0189 0190 MultiplayerScores::~MultiplayerScores() 0191 {} 0192 0193 void MultiplayerScores::clear() 0194 { 0195 Score score; 0196 for (int i=0; i<_scores.size(); i++) { 0197 _nbGames[i] = 0; 0198 QVariant name = _scores[i].data(QStringLiteral( "name" )); 0199 _scores[i] = score; 0200 _scores[i].setData(QStringLiteral( "name" ), name); 0201 _scores[i]._data[QStringLiteral( "mean score" )] = double(0); 0202 _scores[i]._data[QStringLiteral( "nb won games" )] = uint(0); 0203 } 0204 } 0205 0206 void MultiplayerScores::setPlayerCount(uint nb) 0207 { 0208 _nbGames.resize(nb); 0209 _scores.resize(nb); 0210 clear(); 0211 } 0212 0213 void MultiplayerScores::setName(uint i, const QString &name) 0214 { 0215 _scores[i].setData(QStringLiteral( "name" ), name); 0216 } 0217 0218 void MultiplayerScores::addScore(uint i, const Score &score) 0219 { 0220 QVariant name = _scores[i].data(QStringLiteral( "name" )); 0221 double mean = _scores[i].data(QStringLiteral( "mean score" )).toDouble(); 0222 uint won = _scores[i].data(QStringLiteral( "nb won games" )).toUInt(); 0223 _scores[i] = score; 0224 _scores[i].setData(QStringLiteral( "name" ), name); 0225 _nbGames[i]++; 0226 mean += (double(score.score()) - mean) / _nbGames[i]; 0227 _scores[i]._data[QStringLiteral( "mean score" )] = mean; 0228 if ( score.type()==Won ) won++; 0229 _scores[i]._data[QStringLiteral( "nb won games" )] = won; 0230 } 0231 0232 void MultiplayerScores::show(QWidget *parent) 0233 { 0234 QLoggingCategory::setFilterRules(QStringLiteral("games.highscore.debug = true")); 0235 0236 // check consistency 0237 if ( _nbGames.size()<2 ) 0238 qCWarning(GAMES_EXTHIGHSCORE) << "less than 2 players"; 0239 0240 else { 0241 bool ok = true; 0242 uint nb = _nbGames[0]; 0243 for (int i=1; i<_nbGames.size(); i++) 0244 if ( _nbGames[i]!=nb ) ok = false; 0245 if (!ok) 0246 qCWarning(GAMES_EXTHIGHSCORE) << "players have not same number of games"; 0247 } 0248 0249 // order the players according to the number of won games 0250 QList<Score> ordered; 0251 for (int i=0; i<_scores.size(); i++) { 0252 uint won = _scores[i].data(QStringLiteral( "nb won games" )).toUInt(); 0253 double mean = _scores[i].data(QStringLiteral( "mean score" )).toDouble(); 0254 QList<Score>::iterator it; 0255 for(it = ordered.begin(); it!=ordered.end(); ++it) { 0256 uint cwon = (*it).data(QStringLiteral( "nb won games" )).toUInt(); 0257 double cmean = (*it).data(QStringLiteral( "mean score" )).toDouble(); 0258 if ( won<cwon || (won==cwon && mean<cmean) ) { 0259 ordered.insert(it, _scores[i]); 0260 break; 0261 } 0262 } 0263 if ( it==ordered.end() ) ordered.push_back(_scores[i]); 0264 } 0265 0266 // show the scores 0267 KPageDialog dialog(parent); 0268 dialog.setWindowTitle(i18nc("@title:window", "Multiplayers Scores")); 0269 // TODO dialog.setButtons(KDialog::Close); 0270 dialog.setModal(true); 0271 dialog.setFaceType(KPageDialog::Plain); 0272 KPageWidgetItem *page = new KPageWidgetItem( new QLabel(QLatin1String( "" )), QLatin1String( "" ) ); 0273 QHBoxLayout *hbox = new QHBoxLayout(page->widget()); 0274 //hbox->setMargin(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing)); 0275 //hbox->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing)); 0276 0277 QWidget *vbox = new QWidget(page->widget()); 0278 hbox->addWidget(vbox); 0279 if ( _nbGames[0]==0 ) (void)new QLabel(i18n("No game played."), vbox); 0280 else { 0281 (void)new QLabel(i18n("Scores for last game:"), vbox); 0282 (void)new LastMultipleScoresList(ordered, vbox); 0283 } 0284 0285 if ( _nbGames[0]>1 ) { 0286 vbox = new QWidget(page->widget()); 0287 hbox->addWidget(vbox); 0288 (void)new QLabel(i18n("Scores for the last %1 games:", 0289 _nbGames[0]), vbox); 0290 (void)new TotalMultipleScoresList(ordered, vbox); 0291 } 0292 0293 //dialog.showButtonSeparator(false); 0294 dialog.addPage(page); 0295 dialog.exec(); 0296 } 0297 0298 QDataStream &operator <<(QDataStream &s, const MultiplayerScores &score) 0299 { 0300 s << score._scores; 0301 s << score._nbGames; 0302 return s; 0303 } 0304 0305 QDataStream &operator >>(QDataStream &s, MultiplayerScores &score) 0306 { 0307 0308 0309 s >> score._scores; 0310 s >> score._nbGames; 0311 return s; 0312 } 0313 0314 } // namespace