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