File indexing completed on 2024-04-21 04:05:22

0001 /*
0002     This file is part of the KDE games library
0003     SPDX-FileCopyrightText: 2008 Andreas Pakulat <apaku@gmx.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 #include "carddeckinfo.h"
0009 #include "carddeckinfo_p.h"
0010 
0011 #include <QDir>
0012 #include <QFileInfo>
0013 #include <QRandomGenerator>
0014 #include <QStandardPaths>
0015 
0016 #include <KConfig>
0017 #include <KConfigGroup>
0018 #include <KLocalizedString>
0019 #include "lskat_debug.h"
0020 
0021 // KConfig entries
0022 #define CONF_CARD QString::fromLatin1("Cardname")
0023 
0024 /**
0025  * Local static information.
0026  */
0027 class KCardThemeInfoStatic
0028 {
0029 public:
0030     KCardThemeInfoStatic()
0031     {
0032         readDecks();
0033     }
0034     ~KCardThemeInfoStatic()
0035     {
0036     }
0037 
0038     void readDecks()
0039     {
0040         // Empty data
0041         themeNameMap.clear();
0042 
0043         // Add SVG card sets
0044         QStringList list;
0045         const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("carddecks"), QStandardPaths::LocateDirectory);
0046         for (const QString& dir : dirs) {
0047             const QStringList deckFolderNames = QDir(dir).entryList({QStringLiteral("svg*")});
0048             list.reserve(list.size() + deckFolderNames.size());
0049             for (const QString& deck : deckFolderNames) {
0050                 list.append(dir + QLatin1Char('/') + deck + QStringLiteral("/index.desktop"));
0051             }
0052         }
0053 
0054         for (const QString &deckPath : std::as_const(list)) {
0055             KConfig cfg(deckPath, KConfig::SimpleConfig);
0056             KConfigGroup cfgcg(&cfg, QStringLiteral("KDE Backdeck"));
0057             QString path = deckPath.left(deckPath.lastIndexOf(QLatin1Char('/')) + 1);
0058             Q_ASSERT(path[path.length() - 1] == QLatin1Char('/'));
0059             QPixmap pixmap(path + cfgcg.readEntry("Preview", "12c.png"));
0060             if (pixmap.isNull()) continue;
0061 
0062             QString idx  = cfgcg.readEntryUntranslated("Name", i18n("unnamed"));
0063             QString name = cfgcg.readEntry("Name", i18n("unnamed"));
0064             KCardThemeInfo info;
0065             info.name         = name;
0066             info.noi18Name    = idx;
0067             info.comment      = cfgcg.readEntry("Comment", QString());
0068             info.preview      = pixmap;
0069             info.path         = path;
0070 
0071             info.back         = cfgcg.readEntry("Back", QString());
0072             // if (!info.back.isNull()) qCDebug(LSKAT_LOG) << "FOUND BACK " << info.back;
0073             info.isDefault    = cfgcg.readEntry("Default", false);
0074 
0075             QString svg    = cfgcg.readEntry("SVG", QString());
0076             if (!svg.isEmpty())
0077             {
0078                 QFileInfo svgInfo(QDir(path), svg);
0079                 info.svgfile = svgInfo.filePath();
0080                 themeNameMap[idx] = info;
0081             }
0082         }
0083     }
0084 
0085     /** The card front sides for SVG decks. */
0086     QMap<QString, KCardThemeInfo> themeNameMap;
0087 
0088     /** The default front side name. */
0089     QString defaultDeck;
0090 };
0091 
0092 Q_GLOBAL_STATIC(KCardThemeInfoStatic, deckinfoStatic)
0093 
0094 QDebug operator<<(QDebug debug, const KCardThemeInfo &cn)
0095 {
0096     return debug << "name: " << cn.name
0097                  << " noi18Name: " << cn.noi18Name
0098                  << " comment: " << cn.comment
0099                  << " path: " << cn.path
0100                  << " back: " << cn.back
0101                  << " preview: " << cn.preview
0102                  << " svgfile: " << cn.svgfile
0103                  << " isDefault: " << cn.isDefault;
0104 }
0105 
0106 namespace CardDeckInfo
0107 {
0108 // Retrieve default card set name
0109 QString defaultDeckName()
0110 {
0111     QString noDefault;
0112     // Count filtered cards
0113     QMap<QString, KCardThemeInfo> temp = deckinfoStatic->themeNameMap;
0114     QMapIterator<QString, KCardThemeInfo> it(temp);
0115     while (it.hasNext())
0116     {
0117         it.next();
0118         KCardThemeInfo v = it.value();
0119         // Filter
0120         if (v.isDefault) return v.noi18Name;
0121         // Collect any deck if no default is stored
0122         noDefault = v.noi18Name;
0123     }
0124     if (noDefault.isNull()) qCCritical(LSKAT_LOG) << "Could not find default card name";
0125     return noDefault;
0126 }
0127 
0128 // Retrieve a random card name
0129 QString randomDeckName()
0130 {
0131     // Collect matching items
0132     QStringList list = deckinfoStatic->themeNameMap.keys();
0133     // Draw random one
0134     int d = QRandomGenerator::system()->bounded(list.count());
0135     return list.at(d);
0136 }
0137 
0138 // Retrieve the SVG file belonging to the given card fronts.
0139 QString svgFilePath(const QString &name)
0140 {
0141     if (!deckinfoStatic->themeNameMap.contains(name)) return QString();
0142     const KCardThemeInfo &v = deckinfoStatic->themeNameMap[name];
0143     return v.svgfile;
0144 }
0145 
0146 QStringList deckNames()
0147 {
0148     return deckinfoStatic->themeNameMap.keys();
0149 }
0150 
0151 KCardThemeInfo deckInfo(const QString &name)
0152 {
0153     if (deckinfoStatic->themeNameMap.contains(name))
0154         return deckinfoStatic->themeNameMap.value(name);
0155     return KCardThemeInfo();
0156 }
0157 
0158 QString deckName(const KConfigGroup &group, const QString &defaultTheme)
0159 {
0160     QString theme = group.readEntry(CONF_CARD, defaultTheme);
0161     if (!deckNames().contains(theme))
0162         return defaultTheme;
0163     return theme;
0164 }
0165 
0166 void writeDeckName(KConfigGroup &group, const QString &theme)
0167 {
0168     group.writeEntry(CONF_CARD, theme);
0169 }
0170 }