File indexing completed on 2024-05-12 15:59:54
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2003 Patrick Julien <freak@codepimps.org> 0003 SPDX-FileCopyrightText: 2005 Boudewijn Rempt <boud@valdyas.org> 0004 SPDX-FileCopyrightText: 2007 Jan Hambrecht <jaham@gmx.net> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 #include <KoResource.h> 0009 0010 #include <QDomElement> 0011 #include <QFileInfo> 0012 #include <QDebug> 0013 #include <QImage> 0014 #include <QBuffer> 0015 0016 #include <kis_debug.h> 0017 #include "KoMD5Generator.h" 0018 #include "kis_assert.h" 0019 0020 #include "KoResourceLoadResult.h" 0021 0022 0023 struct KoResourceSPStaticRegistrar { 0024 KoResourceSPStaticRegistrar() { 0025 qRegisterMetaType<KoResourceSP>("KoResourceSP"); 0026 } 0027 }; 0028 static KoResourceSPStaticRegistrar __registrar1; 0029 0030 0031 struct Q_DECL_HIDDEN KoResource::Private { 0032 int version {-1}; 0033 int resourceId {-1}; 0034 bool valid {false}; 0035 bool active {true}; 0036 bool permanent {false}; 0037 bool dirty {false}; 0038 QString name; 0039 QString filename; 0040 QString storageLocation; 0041 QString md5sum; 0042 QImage image; 0043 QMap<QString, QVariant> metadata; 0044 }; 0045 0046 KoResource::KoResource() 0047 : d(new Private) 0048 { 0049 } 0050 0051 KoResource::KoResource(const QString& filename) 0052 : d(new Private) 0053 { 0054 d->filename = filename; 0055 d->name = QFileInfo(filename).fileName(); 0056 } 0057 0058 KoResource::~KoResource() 0059 { 0060 delete d; 0061 } 0062 0063 KoResource::KoResource(const KoResource &rhs) 0064 : d(new Private(*rhs.d)) 0065 { 0066 } 0067 0068 bool KoResource::load(KisResourcesInterfaceSP resourcesInterface) 0069 { 0070 QFile file(filename()); 0071 0072 if (!file.exists()) { 0073 qWarning() << "Resource file doesn't exist: " << filename(); 0074 return false; 0075 } 0076 0077 if (file.size() == 0) { 0078 qWarning() << "Resource file is empty: " << filename(); 0079 return false; 0080 } 0081 0082 if (!file.open(QIODevice::ReadOnly)) { 0083 qWarning() << "Cannot open resource file for reading" << filename(); 0084 return false; 0085 } 0086 0087 const bool res = loadFromDevice(&file, resourcesInterface); 0088 0089 if (!res) { 0090 qWarning() << "Could not load resource file" << filename(); 0091 } 0092 0093 file.close(); 0094 0095 return res; 0096 } 0097 0098 bool KoResource::save() 0099 { 0100 if (filename().isEmpty()) return false; 0101 0102 QFile file(filename()); 0103 0104 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { 0105 warnKrita << "Can't open file for writing" << filename(); 0106 return false; 0107 } 0108 0109 saveToDevice(&file); 0110 0111 file.close(); 0112 return true; 0113 } 0114 0115 bool KoResource::saveToDevice(QIODevice *dev) const 0116 { 0117 Q_UNUSED(dev); 0118 return true; 0119 } 0120 0121 QImage KoResource::image() const 0122 { 0123 return d->image; 0124 } 0125 0126 void KoResource::updateThumbnail() 0127 { 0128 } 0129 0130 void KoResource::updateLinkedResourcesMetaData(KisResourcesInterfaceSP /*resourcesInterface*/) 0131 { 0132 } 0133 0134 QImage KoResource::thumbnail() const 0135 { 0136 return image(); 0137 } 0138 0139 QString KoResource::thumbnailPath() const 0140 { 0141 return QString(); 0142 } 0143 0144 void KoResource::setImage(const QImage &image) 0145 { 0146 d->image = image; 0147 } 0148 0149 QString KoResource::md5Sum(bool generateIfEmpty) const 0150 { 0151 // [this assert is disputable] ephemeral resources have no md5 0152 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!isEphemeral(), QString()); 0153 0154 if (d->md5sum.isEmpty() && generateIfEmpty) { 0155 // non-serializable resources should always have an externally generated md5 0156 KIS_SAFE_ASSERT_RECOVER_NOOP(isSerializable()); 0157 dbgResources << "No MD5 for" << this << this->name(); 0158 QBuffer buf; 0159 buf.open(QFile::WriteOnly); 0160 saveToDevice(&buf); 0161 buf.close(); 0162 const_cast<KoResource*>(this)->setMD5Sum(KoMD5Generator::generateHash(buf.data())); 0163 } 0164 return d->md5sum; 0165 } 0166 0167 void KoResource::setMD5Sum(const QString &md5sum) 0168 { 0169 /// ephemeral resources have no md5, trying to assign 0170 /// them one is considered an error 0171 KIS_SAFE_ASSERT_RECOVER_RETURN(!isEphemeral()); 0172 0173 if (valid()) { 0174 Q_ASSERT(!md5sum.isEmpty()); 0175 } 0176 d->md5sum = md5sum; 0177 } 0178 0179 QString KoResource::filename() const 0180 { 0181 return d->filename; 0182 } 0183 0184 void KoResource::setFilename(const QString& filename) 0185 { 0186 d->filename = QFileInfo(filename).fileName(); 0187 } 0188 0189 QString KoResource::name() const 0190 { 0191 return d->name; 0192 } 0193 0194 void KoResource::setName(const QString& name) 0195 { 0196 d->name = name; 0197 } 0198 0199 bool KoResource::valid() const 0200 { 0201 return d->valid; 0202 } 0203 0204 void KoResource::setValid(bool valid) 0205 { 0206 d->valid = valid; 0207 } 0208 0209 bool KoResource::active() const 0210 { 0211 return d->active; 0212 } 0213 0214 void KoResource::setActive(bool active) 0215 { 0216 d->active = active; 0217 } 0218 0219 0220 QString KoResource::defaultFileExtension() const 0221 { 0222 return QString(); 0223 } 0224 0225 bool KoResource::permanent() const 0226 { 0227 return d->permanent; 0228 } 0229 0230 void KoResource::setPermanent(bool permanent) 0231 { 0232 d->permanent = permanent; 0233 } 0234 0235 int KoResource::resourceId() const 0236 { 0237 return d->resourceId; 0238 } 0239 0240 QList<KoResourceLoadResult> KoResource::requiredResources(KisResourcesInterfaceSP globalResourcesInterface) const 0241 { 0242 return linkedResources(globalResourcesInterface) + embeddedResources(globalResourcesInterface); 0243 } 0244 0245 QList<KoResourceLoadResult> KoResource::linkedResources(KisResourcesInterfaceSP globalResourcesInterface) const 0246 { 0247 QList<KoResourceLoadResult> list; 0248 Q_UNUSED(list); 0249 0250 Q_UNUSED(globalResourcesInterface); 0251 return {}; 0252 } 0253 0254 QList<KoResourceLoadResult> KoResource::embeddedResources(KisResourcesInterfaceSP globalResourcesInterface) const 0255 { 0256 Q_UNUSED(globalResourcesInterface); 0257 return {}; 0258 } 0259 0260 QList<int> KoResource::requiredCanvasResources() const 0261 { 0262 return {}; 0263 } 0264 0265 QString KoResource::storageLocation() const 0266 { 0267 return d->storageLocation; 0268 } 0269 0270 void KoResource::setDirty(bool value) 0271 { 0272 d->dirty = value; 0273 } 0274 0275 bool KoResource::isDirty() const 0276 { 0277 return d->dirty; 0278 } 0279 0280 void KoResource::addMetaData(QString key, QVariant value) 0281 { 0282 d->metadata.insert(key, value); 0283 } 0284 0285 QMap<QString, QVariant> KoResource::metadata() const 0286 { 0287 return d->metadata; 0288 } 0289 0290 int KoResource::version() const 0291 { 0292 return d->version; 0293 } 0294 0295 void KoResource::setVersion(int version) 0296 { 0297 d->version = version; 0298 } 0299 0300 void KoResource::setResourceId(int id) 0301 { 0302 d->resourceId = id; 0303 } 0304 0305 KoResourceSignature KoResource::signature() const 0306 { 0307 return KoResourceSignature(resourceType().first, md5Sum(false), filename(), name()); 0308 } 0309 0310 bool KoResource::isEphemeral() const 0311 { 0312 return false; 0313 } 0314 0315 bool KoResource::isSerializable() const 0316 { 0317 return !isEphemeral(); 0318 } 0319 0320 void KoResource::setStorageLocation(const QString &location) 0321 { 0322 d->storageLocation = location; 0323 }