File indexing completed on 2024-04-21 04:05:21
0001 /* 0002 SPDX-FileCopyrightText: 1997 Mathias Mueller <in5y158@public.uni-hamburg.de> 0003 SPDX-FileCopyrightText: 2006 Mauricio Piacentini <mauricio@tabuleiro.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 // own 0009 #include "kmahjonggbackground.h" 0010 0011 // Qt 0012 #include <QFile> 0013 #include <QPainter> 0014 #include <QPixmap> 0015 #include <QPixmapCache> 0016 #include <QSvgRenderer> 0017 #include <QGuiApplication> 0018 0019 // KF 0020 #include <KConfig> 0021 #include <KConfigGroup> 0022 #include <KLocalizedString> 0023 0024 // LibKMahjongg 0025 #include "libkmahjongg_debug.h" 0026 0027 class KMahjonggBackgroundPrivate 0028 { 0029 public: 0030 KMahjonggBackgroundPrivate() = default; 0031 0032 public: 0033 QString name; 0034 QString description; 0035 QString license; 0036 QString copyrightText; 0037 QString version; 0038 QString website; 0039 QString bugReportUrl; 0040 QString authorName; 0041 QString authorEmailAddress; 0042 0043 QString pixmapCacheNameFromElementId(const QString &elementid, short width, short height); 0044 QPixmap renderBG(short width, short height); 0045 0046 QPixmap backgroundPixmap; 0047 QBrush backgroundBrush; 0048 QString filename; 0049 QString graphicspath; 0050 short w = 1; 0051 short h = 1; 0052 0053 QSvgRenderer svg; 0054 0055 bool graphicsLoaded = false; 0056 bool isPlain = false; 0057 bool isTiled = true; 0058 bool isSVG = false; 0059 }; 0060 0061 KMahjonggBackground::KMahjonggBackground() 0062 : d_ptr(new KMahjonggBackgroundPrivate) 0063 { 0064 } 0065 0066 KMahjonggBackground::~KMahjonggBackground() = default; 0067 0068 bool KMahjonggBackground::loadDefault() 0069 { 0070 // Set default background here. 0071 const QString bgPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kmahjongglib/backgrounds/egyptian.desktop")); 0072 qCDebug(LIBKMAHJONGG_LOG) << "Inside LoadDefault(), located background at" << bgPath; 0073 if (bgPath.isEmpty()) { 0074 return false; 0075 } 0076 return load(bgPath, 0, 0); 0077 } 0078 0079 #define kBGVersionFormat 1 0080 0081 bool KMahjonggBackground::load(const QString &file, short width, short height) 0082 { 0083 Q_D(KMahjonggBackground); 0084 0085 // qCDebug(LIBKMAHJONGG_LOG) << "Background loading"; 0086 d->isSVG = false; 0087 0088 // qCDebug(LIBKMAHJONGG_LOG) << "Attempting to load .desktop at" << file; 0089 0090 // verify if it is a valid file first and if we can open it 0091 QFile bgfile(file); 0092 if (!bgfile.open(QIODevice::ReadOnly)) { 0093 return false; 0094 } 0095 bgfile.close(); 0096 0097 KConfig bgconfig(file, KConfig::SimpleConfig); 0098 KConfigGroup group = bgconfig.group(QStringLiteral("KMahjonggBackground")); 0099 0100 d->isPlain = group.readEntry("Plain", 0) != 0; 0101 d->name = group.readEntry("Name"); // Returns translated data 0102 d->description = group.readEntry("Description"); 0103 d->license = group.readEntry("License"); 0104 d->copyrightText = group.readEntry("Copyright"); 0105 d->version = group.readEntry("Version"); 0106 d->website = group.readEntry("Website"); 0107 d->bugReportUrl = group.readEntry("BugReportUrl"); 0108 d->authorName = group.readEntry("Author"); 0109 d->authorEmailAddress = group.readEntry("AuthorEmail"); 0110 0111 // Version control 0112 int bgversion = group.readEntry("VersionFormat", 0); 0113 // Format is increased when we have incompatible changes, meaning that older clients are not able to use the remaining information safely 0114 if (bgversion > kBGVersionFormat) { 0115 return false; 0116 } 0117 0118 if (d->isPlain) { 0119 // qCDebug(LIBKMAHJONGG_LOG) << "Using plain background"; 0120 d->graphicspath.clear(); 0121 d->filename = file; 0122 return true; 0123 } 0124 0125 QString graphName = group.readEntry("FileName"); 0126 0127 d->graphicspath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kmahjongglib/backgrounds/") + graphName); 0128 0129 qCDebug(LIBKMAHJONGG_LOG) << "Using background at" << d->graphicspath; 0130 0131 if (d->graphicspath.isEmpty()) { 0132 return false; 0133 } 0134 0135 if (group.readEntry("Tiled", 0) != 0) { 0136 d->w = group.readEntry("Width", 0); 0137 d->h = group.readEntry("Height", 0); 0138 d->isTiled = true; 0139 } else { 0140 d->w = width; 0141 d->h = height; 0142 d->isTiled = false; 0143 } 0144 d->graphicsLoaded = false; 0145 d->filename = file; 0146 return true; 0147 } 0148 0149 bool KMahjonggBackground::loadGraphics() 0150 { 0151 Q_D(KMahjonggBackground); 0152 0153 if (d->graphicsLoaded || d->isPlain) { 0154 return true; 0155 } 0156 0157 d->svg.load(d->graphicspath); 0158 if (d->svg.isValid()) { 0159 d->isSVG = true; 0160 } else { 0161 // qCDebug(LIBKMAHJONGG_LOG) << "could not load svg"; 0162 return false; 0163 } 0164 return true; 0165 } 0166 0167 void KMahjonggBackground::sizeChanged(int newW, int newH) 0168 { 0169 Q_D(KMahjonggBackground); 0170 0171 // in tiled mode we do not care about the whole field size 0172 if (d->isTiled || d->isPlain) { 0173 return; 0174 } 0175 0176 if (newW == d->w && newH == d->h) { 0177 return; 0178 } 0179 d->w = newW; 0180 d->h = newH; 0181 } 0182 0183 QString KMahjonggBackgroundPrivate::pixmapCacheNameFromElementId(const QString &elementid, short width, short height) 0184 { 0185 return name + elementid + QStringLiteral("W%1H%2").arg(width).arg(height); 0186 } 0187 0188 QPixmap KMahjonggBackgroundPrivate::renderBG(short width, short height) 0189 { 0190 QPixmap qiRend(width, height); 0191 qiRend.fill(Qt::transparent); 0192 0193 if (svg.isValid()) { 0194 QPainter p(&qiRend); 0195 svg.render(&p); 0196 } 0197 return qiRend; 0198 } 0199 0200 QBrush &KMahjonggBackground::getBackground() 0201 { 0202 Q_D(KMahjonggBackground); 0203 0204 if (d->isPlain) { 0205 d->backgroundBrush = QBrush(QPixmap()); 0206 } else { 0207 const qreal dpr = qApp->devicePixelRatio(); 0208 const short width = d->w * dpr; 0209 const short height = d->h * dpr; 0210 0211 // using raw pixmap size with cache id, as the rendering is done dpr-ignorant 0212 const QString pixmapCacheName = d->pixmapCacheNameFromElementId(d->filename, width, height); 0213 if (!QPixmapCache::find(pixmapCacheName, &d->backgroundPixmap)) { 0214 d->backgroundPixmap = d->renderBG(width, height); 0215 d->backgroundPixmap.setDevicePixelRatio(dpr); 0216 QPixmapCache::insert(pixmapCacheName, d->backgroundPixmap); 0217 } 0218 d->backgroundBrush = QBrush(d->backgroundPixmap); 0219 } 0220 return d->backgroundBrush; 0221 } 0222 0223 QString KMahjonggBackground::path() const 0224 { 0225 Q_D(const KMahjonggBackground); 0226 0227 return d->filename; 0228 } 0229 0230 QString KMahjonggBackground::name() const 0231 { 0232 Q_D(const KMahjonggBackground); 0233 0234 return d->name; 0235 } 0236 0237 QString KMahjonggBackground::description() const 0238 { 0239 Q_D(const KMahjonggBackground); 0240 0241 return d->description; 0242 } 0243 0244 QString KMahjonggBackground::license() const 0245 { 0246 Q_D(const KMahjonggBackground); 0247 0248 return d->license; 0249 } 0250 0251 QString KMahjonggBackground::copyrightText() const 0252 { 0253 Q_D(const KMahjonggBackground); 0254 0255 return d->copyrightText; 0256 } 0257 0258 QString KMahjonggBackground::version() const 0259 { 0260 Q_D(const KMahjonggBackground); 0261 0262 return d->version; 0263 } 0264 0265 QString KMahjonggBackground::website() const 0266 { 0267 Q_D(const KMahjonggBackground); 0268 0269 return d->website; 0270 } 0271 0272 QString KMahjonggBackground::bugReportUrl() const 0273 { 0274 Q_D(const KMahjonggBackground); 0275 0276 return d->bugReportUrl; 0277 } 0278 0279 QString KMahjonggBackground::authorName() const 0280 { 0281 Q_D(const KMahjonggBackground); 0282 0283 return d->authorName; 0284 } 0285 0286 QString KMahjonggBackground::authorEmailAddress() const 0287 { 0288 Q_D(const KMahjonggBackground); 0289 0290 return d->authorEmailAddress; 0291 } 0292 0293 bool KMahjonggBackground::isPlain() const 0294 { 0295 Q_D(const KMahjonggBackground); 0296 0297 return d->isPlain; 0298 }