File indexing completed on 2024-04-21 04:03:58

0001 /*
0002     SPDX-FileCopyrightText: 2001-2004 Nicolas Hadacek <hadacek@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "kexthighscore.h"
0008 
0009 #include <QUrlQuery>
0010 
0011 #include "kexthighscore_internal.h"
0012 #include "kexthighscore_gui.h"
0013 
0014 Q_LOGGING_CATEGORY(GAMES_EXTHIGHSCORE, "games.exthighscore")
0015 
0016 namespace KExtHighscore
0017 {
0018 
0019 //-----------------------------------------------------------------------------
0020 ManagerPrivate *internal = nullptr;
0021 
0022 uint gameType()
0023 {
0024     internal->checkFirst();
0025     return internal->gameType();
0026 }
0027 
0028 void setGameType(uint type)
0029 {
0030     internal->setGameType(type);
0031 }
0032 
0033 bool configure(QWidget *parent)
0034 {
0035     internal->checkFirst();
0036     ConfigDialog *cd = new ConfigDialog(parent);
0037     cd->exec();
0038     bool saved = cd->hasBeenSaved();
0039     delete cd;
0040     return saved;
0041 }
0042 
0043 void show(QWidget *parent, int rank)
0044 {
0045     HighscoresDialog *hd = new HighscoresDialog(rank, parent);
0046     hd->exec();
0047     delete hd;
0048 }
0049 
0050 void submitScore(const Score &score, QWidget *widget)
0051 {
0052     int rank = internal->submitScore(score, widget,
0053                                      internal->showMode!=Manager::NeverShow);
0054 
0055     switch (internal->showMode) {
0056     case Manager::AlwaysShow:
0057         show(widget, -1);
0058         break;
0059     case Manager::ShowForHigherScore:
0060         if ( rank!=-1) show(widget, rank);
0061         break;
0062     case Manager::ShowForHighestScore:
0063         if ( rank==0 ) show(widget, rank);
0064         break;
0065     case Manager::NeverShow:
0066         break;
0067     }
0068 }
0069 
0070 void show(QWidget *widget)
0071 {
0072     internal->checkFirst();
0073     show(widget, -1);
0074 }
0075 
0076 Score lastScore()
0077 {
0078     internal->checkFirst();
0079     internal->hsConfig().readCurrentConfig();
0080     uint nb = internal->scoreInfos().maxNbEntries();
0081     return internal->readScore(nb-1);
0082 }
0083 
0084 Score firstScore()
0085 {
0086     internal->checkFirst();
0087     internal->hsConfig().readCurrentConfig();
0088     return internal->readScore(0);
0089 }
0090 
0091 
0092 //-----------------------------------------------------------------------------
0093 Manager::Manager(uint nbGameTypes, uint maxNbEntries)
0094 {
0095     QLoggingCategory::setFilterRules(QStringLiteral("games.highscore.debug = true"));
0096   
0097     Q_ASSERT(nbGameTypes);
0098     Q_ASSERT(maxNbEntries);
0099         
0100     if (internal)
0101     {
0102       qCWarning(GAMES_EXTHIGHSCORE) << "A highscore object already exists";
0103       abort();
0104     }
0105     internal = new ManagerPrivate(nbGameTypes, *this);
0106     internal->init(maxNbEntries);
0107 }
0108 
0109 Manager::~Manager()
0110 {
0111     delete internal;
0112     internal = nullptr;
0113 }
0114 
0115 void Manager::setTrackLostGames(bool track)
0116 {
0117     internal->trackLostGames = track;
0118 }
0119 
0120 void Manager::setTrackDrawGames(bool track)
0121 {
0122     internal->trackDrawGames = track;
0123 }
0124 
0125 void Manager::setShowStatistics(bool show)
0126 {
0127     internal->showStatistics = show;
0128 }
0129 
0130 void Manager::setShowDrawGamesStatistic(bool show)
0131 {
0132     internal->showDrawGames = show;
0133 }
0134 
0135 void Manager::setWWHighscores(const QUrl &url, const QString &version)
0136 {
0137     Q_ASSERT( url.isValid() );
0138     internal->serverURL = url;
0139     const char *HS_WW_URL = "ww hs url";
0140     ConfigGroup cg;
0141     if ( cg.hasKey(HS_WW_URL) )
0142         internal->serverURL = QUrl(cg.readEntry(HS_WW_URL));
0143     else cg.writeEntry(HS_WW_URL, url.url());
0144     internal->version = version;
0145 }
0146 
0147 void Manager::setScoreHistogram(const QList<uint> &scores,
0148                                 ScoreTypeBound type)
0149 {
0150     Q_ASSERT( scores.size()>=2 );
0151     for (int i=0; i<scores.size()-1; i++)
0152         Q_ASSERT( scores[i]<scores[i+1] );
0153     internal->playerInfos().createHistoItems(scores, type==ScoreBound);
0154 }
0155 
0156 void Manager::setShowMode(ShowMode mode)
0157 {
0158     internal->showMode = mode;
0159 }
0160 
0161 void Manager::setScoreType(ScoreType type)
0162 {
0163     switch (type) {
0164     case Normal:
0165         return;
0166     case MinuteTime: {
0167         Item *item = createItem(ScoreDefault);
0168         item->setPrettyFormat(Item::MinuteTime);
0169         setScoreItem(0, item);
0170 
0171         item = createItem(MeanScoreDefault);
0172         item->setPrettyFormat(Item::MinuteTime);
0173         setPlayerItem(MeanScore, item);
0174 
0175         item = createItem(BestScoreDefault);
0176         item->setPrettyFormat(Item::MinuteTime);
0177         setPlayerItem(BestScore, item);
0178         return;
0179     }
0180     }
0181 }
0182 
0183 void Manager::submitLegacyScore(const Score &score) const
0184 {
0185     internal->submitLocal(score);
0186 }
0187 
0188 bool Manager::isStrictlyLess(const Score &s1, const Score &s2) const
0189 {
0190     return s1.score()<s2.score();
0191 }
0192 
0193 Item *Manager::createItem(ItemType type)
0194 {
0195     Item *item = nullptr;
0196     switch (type) {
0197     case ScoreDefault:
0198         item = new Item((uint)0, i18n("Score"), Qt::AlignRight);
0199         break;
0200     case MeanScoreDefault:
0201         item = new Item((double)0, i18n("Mean Score"), Qt::AlignRight);
0202         item->setPrettyFormat(Item::OneDecimal);
0203         item->setPrettySpecial(Item::DefaultNotDefined);
0204         break;
0205     case BestScoreDefault:
0206         item = new Item((uint)0, i18n("Best Score"), Qt::AlignRight);
0207         item->setPrettySpecial(Item::DefaultNotDefined);
0208         break;
0209     case ElapsedTime:
0210         item = new Item((uint)0, i18n("Elapsed Time"), Qt::AlignRight);
0211         item->setPrettyFormat(Item::MinuteTime);
0212         item->setPrettySpecial(Item::ZeroNotDefined);
0213         break;
0214     }
0215     return item;
0216 }
0217 
0218 void Manager::setScoreItem(uint worstScore, Item *item)
0219 {
0220     item->setDefaultValue(worstScore);
0221     internal->scoreInfos().setItem(QStringLiteral( "score" ), item);
0222     internal->playerInfos().item(QStringLiteral( "mean score" ))
0223         ->item()->setDefaultValue(double(worstScore));
0224     internal->playerInfos().item(QStringLiteral( "best score" ))
0225         ->item()->setDefaultValue(worstScore);
0226 }
0227 
0228 void Manager::addScoreItem(const QString &name, Item *item)
0229 {
0230     internal->scoreInfos().addItem(name, item, true);
0231 }
0232 
0233 void Manager::setPlayerItem(PlayerItemType type, Item *item)
0234 {
0235     const Item *scoreItem = internal->scoreInfos().item(QStringLiteral( "score" ))->item();
0236     uint def = scoreItem->defaultValue().toUInt();
0237     QString name;
0238     switch (type) {
0239     case MeanScore:
0240         name = QStringLiteral( "mean score" );
0241         item->setDefaultValue(double(def));
0242         break;
0243     case BestScore:
0244         name = QStringLiteral( "best score" );
0245         item->setDefaultValue(def);
0246         break;
0247     }
0248     internal->playerInfos().setItem(name, item);
0249 }
0250 
0251 QString Manager::gameTypeLabel(uint gameType, LabelType type) const
0252 {
0253     QLoggingCategory::setFilterRules(QStringLiteral("games.highscore.debug = true"));
0254     
0255     if ( gameType!=0 )
0256     {
0257       qCWarning(GAMES_EXTHIGHSCORE) << "You need to reimplement KExtHighscore::Manager for "
0258                        << "multiple game types";
0259       abort();
0260     }
0261     switch (type) {
0262     case Icon:
0263     case Standard:
0264     case I18N:     break;
0265     case WW:       return QStringLiteral( "normal" );
0266     }
0267     return QString();
0268 }
0269 
0270 void Manager::addToQueryURL(QUrl &url, const QString &item,
0271                                const QString &content)
0272 {
0273   QUrlQuery urlquery(url);  
0274   Q_ASSERT( !item.isEmpty() && urlquery.queryItemValue(item).isEmpty() );
0275 
0276     QString query = url.query();
0277     if ( !query.isEmpty() ) query += QLatin1Char( '&' );
0278     query += item + QLatin1Char( '=' ) + QLatin1String( QUrl::toPercentEncoding( content ) );
0279     url.setQuery(query);
0280 }
0281 
0282 } // namescape