File indexing completed on 2024-05-12 05:09:23

0001 /***************************************************************************
0002     Copyright (C) 2006-2009 Robby Stephenson <robby@periapsis.org>
0003 
0004  ***************************************************************************/
0005 
0006 /***************************************************************************
0007  *                                                                         *
0008  *   This program is free software; you can redistribute it and/or         *
0009  *   modify it under the terms of the GNU General Public License as        *
0010  *   published by the Free Software Foundation; either version 2 of        *
0011  *   the License or (at your option) version 3 or any later version        *
0012  *   accepted by the membership of KDE e.V. (or its successor approved     *
0013  *   by the membership of KDE e.V.), which shall act as a proxy            *
0014  *   defined in Section 14 of version 3 of the license.                    *
0015  *                                                                         *
0016  *   This program is distributed in the hope that it will be useful,       *
0017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0019  *   GNU General Public License for more details.                          *
0020  *                                                                         *
0021  *   You should have received a copy of the GNU General Public License     *
0022  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0023  *                                                                         *
0024  ***************************************************************************/
0025 
0026 #include "gamecollection.h"
0027 #include "../tellico_debug.h"
0028 
0029 #include <KLocalizedString>
0030 
0031 namespace {
0032   static const char* game_general = I18N_NOOP("General");
0033   static const char* game_personal = I18N_NOOP("Personal");
0034 }
0035 
0036 using Tellico::Data::GameCollection;
0037 
0038 GameCollection::GameCollection(bool addDefaultFields_, const QString& title_)
0039    : Collection(title_.isEmpty() ? i18n("My Video Games") : title_) {
0040   setDefaultGroupField(QStringLiteral("platform"));
0041   if(addDefaultFields_) {
0042     addFields(defaultFields());
0043   }
0044 }
0045 
0046 Tellico::Data::FieldList GameCollection::defaultFields() {
0047   FieldList list;
0048   FieldPtr field;
0049 
0050   list.append(Field::createDefaultField(Field::TitleField));
0051 
0052   QStringList platform;
0053   platform << platformName(XboxSeriesX) << platformName(XboxOne) << platformName(Xbox360) << platformName(Xbox)
0054            << platformName(PlayStation5) << platformName(PlayStation4) << platformName(PlayStation3) << platformName(PlayStation2) << platformName(PlayStation)
0055            << platformName(PlayStationPortable) << platformName(PlayStationVita)
0056            << platformName(NintendoSwitch) << platformName(NintendoWiiU)
0057            << platformName(NintendoWii)  << platformName(Nintendo3DS) << platformName(NintendoDS)
0058            << platformName(Nintendo64)  << platformName(SuperNintendo) << platformName(Nintendo)
0059            << platformName(NintendoGameCube) << platformName(Dreamcast)
0060            << platformName(Windows) << platformName(MacOS) << platformName(Linux);
0061   field = new Field(QStringLiteral("platform"), i18n("Platform"), platform);
0062   field->setCategory(i18n(game_general));
0063   field->setFlags(Field::AllowGrouped);
0064   list.append(field);
0065 
0066   field = new Field(QStringLiteral("genre"), i18n("Genre"));
0067   field->setCategory(i18n(game_general));
0068   field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
0069   field->setFormatType(FieldFormat::FormatPlain);
0070   list.append(field);
0071 
0072   field = new Field(QStringLiteral("year"), i18n("Release Year"), Field::Number);
0073   field->setCategory(i18n(game_general));
0074   field->setFlags(Field::AllowGrouped);
0075   list.append(field);
0076 
0077   field = new Field(QStringLiteral("publisher"), i18nc("Games - Publisher", "Publisher"));
0078   field->setCategory(i18n(game_general));
0079   field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
0080   field->setFormatType(FieldFormat::FormatPlain);
0081   list.append(field);
0082 
0083   field = new Field(QStringLiteral("developer"), i18n("Developer"));
0084   field->setCategory(i18n(game_general));
0085   field->setFlags(Field::AllowCompletion | Field::AllowMultiple | Field::AllowGrouped);
0086   field->setFormatType(FieldFormat::FormatPlain);
0087   list.append(field);
0088 
0089   field = new Field(QStringLiteral("certification"), i18n("ESRB Rating"), esrbRatings());
0090   field->setCategory(i18n(game_general));
0091   field->setFlags(Field::AllowGrouped);
0092   list.append(field);
0093 
0094   field = new Field(QStringLiteral("description"), i18n("Description"), Field::Para);
0095   list.append(field);
0096 
0097   field = new Field(QStringLiteral("rating"), i18n("Personal Rating"), Field::Rating);
0098   field->setCategory(i18n(game_personal));
0099   field->setFlags(Field::AllowGrouped);
0100   list.append(field);
0101 
0102   field = new Field(QStringLiteral("completed"), i18n("Completed"), Field::Bool);
0103   field->setCategory(i18n(game_personal));
0104   list.append(field);
0105 
0106   field = new Field(QStringLiteral("pur_date"), i18n("Purchase Date"));
0107   field->setCategory(i18n(game_personal));
0108   field->setFormatType(FieldFormat::FormatDate);
0109   list.append(field);
0110 
0111   field = new Field(QStringLiteral("gift"), i18n("Gift"), Field::Bool);
0112   field->setCategory(i18n(game_personal));
0113   list.append(field);
0114 
0115   field = new Field(QStringLiteral("pur_price"), i18n("Purchase Price"));
0116   field->setCategory(i18n(game_personal));
0117   list.append(field);
0118 
0119   field = new Field(QStringLiteral("loaned"), i18n("Loaned"), Field::Bool);
0120   field->setCategory(i18n(game_personal));
0121   list.append(field);
0122 
0123   field = new Field(QStringLiteral("cover"), i18n("Cover"), Field::Image);
0124   list.append(field);
0125 
0126   field = new Field(QStringLiteral("comments"), i18n("Comments"), Field::Para);
0127   field->setCategory(i18n(game_personal));
0128   list.append(field);
0129 
0130   list.append(Field::createDefaultField(Field::IDField));
0131   list.append(Field::createDefaultField(Field::CreatedDateField));
0132   list.append(Field::createDefaultField(Field::ModifiedDateField));
0133 
0134   return list;
0135 }
0136 
0137 
0138 QString GameCollection::normalizePlatform(const QString& platformName_) {
0139   if(platformName_.isEmpty()) return QString();
0140   GamePlatform platform = guessPlatform(platformName_);
0141   if(platform == UnknownPlatform) {
0142     QString platformName = platformName_;
0143     if(platformName.startsWith(QStringLiteral("Microsoft"))) {
0144       platformName = platformName.mid(sizeof("Microsoft"));
0145     } else if(platformName.startsWith(QStringLiteral("Sony Playstation"))) {
0146       // default video game collection has no space between 'PlayStation' and #
0147       platformName = QStringLiteral("PlayStation") + platformName.mid(sizeof("Sony Playstation"));
0148     }
0149     myDebug() << "No default name for" << platformName_ << "; return" << platformName;
0150     return platformName;
0151   }
0152   return platformName(platform);
0153 }
0154 
0155 Tellico::Data::GameCollection::GamePlatform GameCollection::guessPlatform(const QString& name_) {
0156   // try to be smart about guessing the platform from its name
0157   if(name_.contains(QStringLiteral("PlayStation"), Qt::CaseInsensitive)) {
0158     if(name_.contains(QStringLiteral("Vita"), Qt::CaseInsensitive)) {
0159       return PlayStationVita;
0160     } else if(name_.contains(QStringLiteral("Portable"), Qt::CaseInsensitive)) {
0161       return PlayStationPortable;
0162     } else if(name_.contains(QStringLiteral("5"))) {
0163       return PlayStation5;
0164     } else if(name_.contains(QStringLiteral("4"))) {
0165       return PlayStation4;
0166     } else if(name_.contains(QStringLiteral("3"))) {
0167       return PlayStation3;
0168     } else if(name_.contains(QStringLiteral("2"))) {
0169       return PlayStation2;
0170     } else {
0171       return PlayStation;
0172     }
0173   } else if(name_.contains(QStringLiteral("PSP"), Qt::CaseInsensitive)) {
0174     return PlayStationPortable;
0175   } else if(name_.contains(QStringLiteral("Xbox"), Qt::CaseInsensitive)) {
0176     if(name_.contains(QStringLiteral("One"), Qt::CaseInsensitive)) {
0177       return XboxOne;
0178     } else if(name_.contains(QStringLiteral("360"))) {
0179       return Xbox360;
0180     } else if(name_.endsWith(QStringLiteral("X"))) {
0181       return XboxSeriesX;
0182     } else {
0183       return Xbox;
0184     }
0185   } else if(name_.contains(QStringLiteral("Switch"), Qt::CaseInsensitive)) {
0186     return NintendoSwitch;
0187   } else if(name_.contains(QStringLiteral("Wii"), Qt::CaseInsensitive)) {
0188     if(name_.contains(QStringLiteral("U"), Qt::CaseInsensitive)) {
0189       return NintendoWiiU;
0190     } else {
0191       return NintendoWii;
0192     }
0193   } else if(name_.contains(QStringLiteral("PC"), Qt::CaseInsensitive) ||
0194             name_.contains(QStringLiteral("Windows"), Qt::CaseInsensitive)) {
0195     return Windows;
0196   } else if(name_.contains(QStringLiteral("Mac"), Qt::CaseInsensitive)) {
0197     return MacOS;
0198   } else if(name_.contains(QStringLiteral("3DS"), Qt::CaseInsensitive)) {
0199     return Nintendo3DS;
0200   } else if(name_.contains(QStringLiteral("DS"), Qt::CaseInsensitive)) {
0201     return NintendoDS;
0202   } else if(name_ == QStringLiteral("Nintendo 64")) {
0203     return Nintendo64;
0204   } else if(name_.contains(QStringLiteral("GameCube"), Qt::CaseInsensitive)) {
0205     return NintendoGameCube;
0206   } else if(name_.contains(QStringLiteral("Advance"), Qt::CaseInsensitive)) {
0207     return GameBoyAdvance;
0208   } else if(name_.contains(QStringLiteral("Game Boy Color"), Qt::CaseInsensitive) ||
0209             name_.contains(QStringLiteral("GameBoy Color"), Qt::CaseInsensitive)) {
0210     return GameBoyColor;
0211   } else if(name_.contains(QStringLiteral("Game Boy"), Qt::CaseInsensitive) ||
0212             name_.contains(QStringLiteral("GameBoy"), Qt::CaseInsensitive)) {
0213     return GameBoy;
0214   } else if(name_.contains(QStringLiteral("SNES"), Qt::CaseInsensitive) ||
0215             name_.contains(QStringLiteral("Super Nintendo"), Qt::CaseInsensitive)) {
0216     return SuperNintendo;
0217     // only return Nintendo if equal or includes Original or Entertainment
0218     // could be platforms like "Nintendo Virtual Boy"
0219   } else if(name_ == QLatin1String("Nintendo") ||
0220             name_ == QLatin1String("NES") ||
0221             name_.contains(QStringLiteral("Nintendo Entertainment"), Qt::CaseInsensitive)) {
0222     return Nintendo;
0223   } else if(name_.contains(QStringLiteral("Genesis"), Qt::CaseInsensitive)) {
0224     return Genesis;
0225   } else if(name_.contains(QStringLiteral("Dreamcast"), Qt::CaseInsensitive)) {
0226     return Dreamcast;
0227   } else if(name_.contains(QStringLiteral("Linux"), Qt::CaseInsensitive)) {
0228     return Linux;
0229   } else if(name_.contains(QStringLiteral("ios"), Qt::CaseInsensitive)) {
0230     return iOS;
0231   } else if(name_.contains(QStringLiteral("Android"), Qt::CaseInsensitive)) {
0232     return Android;
0233   }
0234 //  myDebug() << "No platform guess for" << name_;
0235   return UnknownPlatform;
0236 }
0237 
0238 QString GameCollection::platformName(GamePlatform platform_) {
0239   switch(platform_) {
0240     case Linux:               return i18n("Linux");
0241     case MacOS:               return i18n("Mac OS");
0242     case Windows:             return i18nc("Windows Platform", "Windows");
0243     case iOS:                 return i18nc("iOS Platform", "iOS");
0244     case Android:             return i18nc("Android Platform", "Android");
0245     case Xbox:                return i18n("Xbox");
0246     case Xbox360:             return i18n("Xbox 360");
0247     case XboxOne:             return i18n("Xbox One");
0248     case XboxSeriesX:         return i18n("Xbox Series X");
0249     case PlayStation:         return i18n("PlayStation");
0250     case PlayStation2:        return i18n("PlayStation2");
0251     case PlayStation3:        return i18n("PlayStation3");
0252     case PlayStation4:        return i18n("PlayStation4");
0253     case PlayStation5:        return i18n("PlayStation5");
0254     case PlayStationPortable: return i18nc("PlayStation Portable", "PSP");
0255     case PlayStationVita:     return i18n("PlayStation Vita");
0256     case GameBoy:             return i18n("Game Boy");
0257     case GameBoyColor:        return i18n("Game Boy Color");
0258     case GameBoyAdvance:      return i18n("Game Boy Advance");
0259     case Nintendo:            return i18n("Nintendo");
0260     case SuperNintendo:       return i18n("Super Nintendo");
0261     case Nintendo64:          return i18n("Nintendo 64");
0262     case NintendoGameCube:    return i18n("GameCube");
0263     case NintendoWii:         return i18n("Nintendo Wii");
0264     case NintendoWiiU:        return i18n("Nintendo WiiU");
0265     case NintendoSwitch:      return i18n("Nintendo Switch");
0266     case NintendoDS:          return i18n("Nintendo DS");
0267     case Nintendo3DS:         return i18n("Nintendo 3DS");
0268     case Genesis:             return i18nc("Sega Genesis", "Genesis");
0269     case Dreamcast:           return i18n("Dreamcast");
0270     case UnknownPlatform:     break;
0271     case LastPlatform:        break;
0272   }
0273   myDebug() << "Failed to return platform name for" << platform_;
0274   return QString();
0275 }
0276 
0277 QStringList GameCollection::esrbRatings() {
0278   static const QRegularExpression rx(QLatin1String("\\s*,\\s*"));
0279   QStringList cert = i18nc("Video game ratings - "
0280                            "Unrated, Adults Only, Mature, Teen, Everyone 10+, Everyone, Early Childhood, Pending",
0281                            "Unrated, Adults Only, Mature, Teen, Everyone 10+, Everyone, Early Childhood, Pending")
0282 #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
0283                      .split(rx, QString::SkipEmptyParts);
0284 #else
0285                      .split(rx, Qt::SkipEmptyParts);
0286 #endif
0287   return cert;
0288 }
0289 
0290 QString GameCollection::esrbRating(EsrbRating rating_) {
0291   static const QStringList ratings = esrbRatings();
0292   Q_ASSERT(ratings.size() == 8);
0293   if(ratings.size() < 8) {
0294     myWarning() << "ESRB rating list is badly translated, return empty string";
0295     return QString();
0296   }
0297   switch(rating_) {
0298     case Unrated:        return ratings.at(0);
0299     case Adults:         return ratings.at(1);
0300     case Mature:         return ratings.at(2);
0301     case Teen:           return ratings.at(3);
0302     case Everyone10:     return ratings.at(4);
0303     case Everyone:       return ratings.at(5);
0304     case EarlyChildhood: return ratings.at(6);
0305     case Pending:        return ratings.at(7);
0306     default:
0307       return QString();
0308   }
0309 }