File indexing completed on 2024-05-12 16:45:38

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 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"))) {
0159       return PlayStationVita;
0160     } else if(name_.contains(QStringLiteral("Portable"))) {
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"))) {
0174     return PlayStationPortable;
0175   } else if(name_.contains(QStringLiteral("Xbox"), Qt::CaseInsensitive)) {
0176     if(name_.contains(QStringLiteral("One"))) {
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"))) {
0186     return NintendoSwitch;
0187   } else if(name_.contains(QStringLiteral("Wii"))) {
0188     if(name_.contains(QStringLiteral("U"))) {
0189       return NintendoWiiU;
0190     } else {
0191       return NintendoWii;
0192     }
0193   } else if(name_.contains(QStringLiteral("PC")) ||
0194             name_.contains(QStringLiteral("Windows"))) {
0195     return Windows;
0196   } else if(name_.contains(QStringLiteral("Mac"))) {
0197     return MacOS;
0198   } else if(name_.contains(QStringLiteral("3DS"))) {
0199     return Nintendo3DS;
0200   } else if(name_.contains(QStringLiteral("DS"))) {
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"))) {
0207     return GameBoyAdvance;
0208   } else if(name_.contains(QStringLiteral("Game Boy Color")) || name_.contains(QStringLiteral("GameBoy Color"), Qt::CaseInsensitive)) {
0209     return GameBoyColor;
0210   } else if(name_.contains(QStringLiteral("Game Boy")) || name_.contains(QStringLiteral("GameBoy"), Qt::CaseInsensitive)) {
0211     return GameBoy;
0212   } else if(name_.contains(QStringLiteral("SNES")) || name_.contains(QStringLiteral("Super Nintendo"))) {
0213     return SuperNintendo;
0214     // only return Nintendo if equal or includes Original or Entertainment
0215     // could be platforms like "Nintendo Virtual Boy"
0216   } else if(name_ == QStringLiteral("Nintendo")
0217             || name_ == QStringLiteral("NES")
0218             || name_.contains(QStringLiteral("Nintendo Entertainment"))) {
0219     return Nintendo;
0220   } else if(name_.contains(QStringLiteral("Genesis"))) {
0221     return Genesis;
0222   } else if(name_.contains(QStringLiteral("Dreamcast"))) {
0223     return Dreamcast;
0224   } else if(name_.contains(QStringLiteral("Linux"))) {
0225     return Linux;
0226   } else if(name_.contains(QStringLiteral("ios"), Qt::CaseInsensitive)) {
0227     return iOS;
0228   } else if(name_.contains(QStringLiteral("Android"))) {
0229     return Android;
0230   }
0231 //  myDebug() << "No platform guess for" << name_;
0232   return UnknownPlatform;
0233 }
0234 
0235 QString GameCollection::platformName(GamePlatform platform_) {
0236   switch(platform_) {
0237     case Linux:               return i18n("Linux");
0238     case MacOS:               return i18n("Mac OS");
0239     case Windows:             return i18nc("Windows Platform", "Windows");
0240     case iOS:                 return i18nc("iOS Platform", "iOS");
0241     case Android:             return i18nc("Android Platform", "Android");
0242     case Xbox:                return i18n("Xbox");
0243     case Xbox360:             return i18n("Xbox 360");
0244     case XboxOne:             return i18n("Xbox One");
0245     case XboxSeriesX:         return i18n("Xbox Series X");
0246     case PlayStation:         return i18n("PlayStation");
0247     case PlayStation2:        return i18n("PlayStation2");
0248     case PlayStation3:        return i18n("PlayStation3");
0249     case PlayStation4:        return i18n("PlayStation4");
0250     case PlayStation5:        return i18n("PlayStation5");
0251     case PlayStationPortable: return i18nc("PlayStation Portable", "PSP");
0252     case PlayStationVita:     return i18n("PlayStation Vita");
0253     case GameBoy:             return i18n("Game Boy");
0254     case GameBoyColor:        return i18n("Game Boy Color");
0255     case GameBoyAdvance:      return i18n("Game Boy Advance");
0256     case Nintendo:            return i18n("Nintendo");
0257     case SuperNintendo:       return i18n("Super Nintendo");
0258     case Nintendo64:          return i18n("Nintendo 64");
0259     case NintendoGameCube:    return i18n("GameCube");
0260     case NintendoWii:         return i18n("Nintendo Wii");
0261     case NintendoWiiU:        return i18n("Nintendo WiiU");
0262     case NintendoSwitch:      return i18n("Nintendo Switch");
0263     case NintendoDS:          return i18n("Nintendo DS");
0264     case Nintendo3DS:         return i18n("Nintendo 3DS");
0265     case Genesis:             return i18nc("Sega Genesis", "Genesis");
0266     case Dreamcast:           return i18n("Dreamcast");
0267     case UnknownPlatform:     break;
0268     case LastPlatform:        break;
0269   }
0270   myDebug() << "Failed to return platform name for" << platform_;
0271   return QString();
0272 }
0273 
0274 QStringList GameCollection::esrbRatings() {
0275   static const QRegularExpression rx(QLatin1String("\\s*,\\s*"));
0276   QStringList cert = i18nc("Video game ratings - "
0277                            "Unrated, Adults Only, Mature, Teen, Everyone 10+, Everyone, Early Childhood, Pending",
0278                            "Unrated, Adults Only, Mature, Teen, Everyone 10+, Everyone, Early Childhood, Pending")
0279 #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
0280                      .split(rx, QString::SkipEmptyParts);
0281 #else
0282                      .split(rx, Qt::SkipEmptyParts);
0283 #endif
0284   return cert;
0285 }
0286 
0287 QString GameCollection::esrbRating(EsrbRating rating_) {
0288   static const QStringList ratings = esrbRatings();
0289   Q_ASSERT(ratings.size() == 8);
0290   if(ratings.size() < 8) {
0291     myWarning() << "ESRB rating list is badly translated, return empty string";
0292     return QString();
0293   }
0294   switch(rating_) {
0295     case Unrated:        return ratings.at(0);
0296     case Adults:         return ratings.at(1);
0297     case Mature:         return ratings.at(2);
0298     case Teen:           return ratings.at(3);
0299     case Everyone10:     return ratings.at(4);
0300     case Everyone:       return ratings.at(5);
0301     case EarlyChildhood: return ratings.at(6);
0302     case Pending:        return ratings.at(7);
0303     default:
0304       return QString();
0305   }
0306 }