File indexing completed on 2024-04-28 04:05:04

0001 /*
0002     SPDX-FileCopyrightText: 2012 Stefan Majewsky <majewsky@gmx.net>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "kgametheme.h"
0008 
0009 // own
0010 #include <kdegames_logging.h>
0011 // KF
0012 #include <KConfig>
0013 #include <KConfigGroup>
0014 // Qt
0015 #include <QDir>
0016 #include <QFileInfo>
0017 #include <QStandardPaths>
0018 // Std
0019 #include <utility>
0020 
0021 class KGameThemePrivate
0022 {
0023 public:
0024     const QByteArray m_identifier;
0025     QString m_name, m_description, m_author, m_authorEmail, m_graphicsPath, m_previewPath;
0026     QString m_license;
0027     QString m_copyrightText;
0028     QString m_version;
0029     QString m_website;
0030     QString m_bugReportUrl;
0031     QMap<QString, QString> m_customData;
0032 
0033 public:
0034     explicit KGameThemePrivate(const QByteArray &id)
0035         : m_identifier(id)
0036     {
0037     }
0038 
0039     static QStringList s_configGroupNames;
0040 };
0041 
0042 /*static*/ QStringList KGameThemePrivate::s_configGroupNames;
0043 
0044 KGameTheme::KGameTheme(const QByteArray &identifier, QObject *parent)
0045     : QObject(parent)
0046     , d_ptr(new KGameThemePrivate(identifier))
0047 {
0048 }
0049 
0050 KGameTheme::~KGameTheme() = default;
0051 
0052 QByteArray KGameTheme::identifier() const
0053 {
0054     Q_D(const KGameTheme);
0055 
0056     return d->m_identifier;
0057 }
0058 
0059 #define KGAMETHEME_STRING_PROPERTY(PROP, SETTER)                                                                                                               \
0060     QString KGameTheme::PROP() const                                                                                                                           \
0061     {                                                                                                                                                          \
0062         Q_D(const KGameTheme);                                                                                                                                 \
0063         return d->m_##PROP;                                                                                                                                    \
0064     }                                                                                                                                                          \
0065     void KGameTheme::SETTER(const QString &val)                                                                                                                \
0066     {                                                                                                                                                          \
0067         Q_D(KGameTheme);                                                                                                                                       \
0068         d->m_##PROP = val;                                                                                                                                     \
0069     }
0070 
0071 KGAMETHEME_STRING_PROPERTY(name, setName)
0072 KGAMETHEME_STRING_PROPERTY(description, setDescription)
0073 KGAMETHEME_STRING_PROPERTY(license, setLicense)
0074 KGAMETHEME_STRING_PROPERTY(copyrightText, setCopyrightText)
0075 KGAMETHEME_STRING_PROPERTY(version, setVersion)
0076 KGAMETHEME_STRING_PROPERTY(website, setWebsite)
0077 KGAMETHEME_STRING_PROPERTY(bugReportUrl, setBugReportUrl)
0078 KGAMETHEME_STRING_PROPERTY(author, setAuthor)
0079 KGAMETHEME_STRING_PROPERTY(authorEmail, setAuthorEmail)
0080 KGAMETHEME_STRING_PROPERTY(graphicsPath, setGraphicsPath)
0081 KGAMETHEME_STRING_PROPERTY(previewPath, setPreviewPath)
0082 
0083 QMap<QString, QString> KGameTheme::customData() const
0084 {
0085     Q_D(const KGameTheme);
0086 
0087     return d->m_customData;
0088 }
0089 
0090 QString KGameTheme::customData(const QString &key, const QString &defaultValue) const
0091 {
0092     Q_D(const KGameTheme);
0093 
0094     return d->m_customData.value(key, defaultValue);
0095 }
0096 
0097 void KGameTheme::setCustomData(const QMap<QString, QString> &customData)
0098 {
0099     Q_D(KGameTheme);
0100 
0101     d->m_customData = customData;
0102 }
0103 
0104 bool KGameTheme::readFromDesktopFile(const QString &path_)
0105 {
0106     if (path_.isEmpty()) {
0107         qCDebug(KDEGAMES_LOG) << "Refusing to load theme with no name";
0108         return false;
0109     }
0110     // legacy support: relative paths are resolved with KStandardDirs/appdata
0111     QString path(path_);
0112     if (QFileInfo(path).isRelative()) {
0113         path = QStandardPaths::locate(QStandardPaths::AppDataLocation, path);
0114         if (path.isEmpty()) {
0115             qCDebug(KDEGAMES_LOG) << "Could not find theme description" << path;
0116             return false;
0117         }
0118     }
0119     // default group name
0120     if (KGameThemePrivate::s_configGroupNames.isEmpty()) {
0121         KGameThemePrivate::s_configGroupNames << QStringLiteral("KGameTheme");
0122     }
0123     // open file, look for a known config group
0124     KConfig config(path, KConfig::SimpleConfig);
0125     KConfigGroup group;
0126     for (const QString &groupName : std::as_const(KGameThemePrivate::s_configGroupNames)) {
0127         if (config.hasGroup(groupName)) {
0128             group = config.group(groupName);
0129         }
0130     }
0131     if (!group.isValid()) {
0132         qCDebug(KDEGAMES_LOG) << "Could not read theme description at" << path;
0133         return false;
0134     }
0135     // check format version
0136     if (group.readEntry("VersionFormat", 1) > 1) {
0137         qCDebug(KDEGAMES_LOG) << "Format of theme description too new at" << path;
0138         return false;
0139     }
0140 
0141     // resolve paths
0142     const QFileInfo fi(path);
0143     const QDir dir = fi.dir();
0144     QString graphicsPath = group.readEntry("FileName", QString());
0145     if (!graphicsPath.isEmpty() && QFileInfo(graphicsPath).isRelative())
0146         graphicsPath = dir.absoluteFilePath(graphicsPath);
0147     QString previewPath = group.readEntry("Preview", QString());
0148     if (!previewPath.isEmpty() && QFileInfo(previewPath).isRelative())
0149         previewPath = dir.absoluteFilePath(previewPath);
0150     // create theme
0151     setName(group.readEntry("Name", QString()));
0152     setDescription(group.readEntry("Description", QString()));
0153     setLicense(group.readEntry("License", QString()));
0154     setCopyrightText(group.readEntry("Copyright", QString()));
0155     setVersion(group.readEntry("Version", QString()));
0156     setWebsite(group.readEntry("Website", QString()));
0157     setBugReportUrl(group.readEntry("BugReportUrl", QString()));
0158     setAuthor(group.readEntry("Author", QString()));
0159     setAuthorEmail(group.readEntry("AuthorEmail", QString()));
0160     setGraphicsPath(graphicsPath);
0161     setPreviewPath(previewPath);
0162     setCustomData(group.entryMap());
0163     // store modification date of this file in private property (KGameRenderer
0164     // wants to clear its cache also if the theme description changes)
0165     setProperty("_k_themeDescTimestamp", fi.lastModified().toSecsSinceEpoch());
0166     return true;
0167 }
0168 
0169 #include "moc_kgametheme.cpp"