File indexing completed on 2025-01-26 04:04:55

0001 /*
0002  * This file is part of Krita
0003  *
0004  * SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #include <FlakeDebug.h>
0010 #include <KoStore.h>
0011 #include <KoStoreDevice.h>
0012 #include <QBuffer>
0013 #include <QDir>
0014 #include <QFileInfo>
0015 #include <QTextDecoder>
0016 #include <kis_assert.h>
0017 
0018 #include "KisSeExprScript.h"
0019 
0020 struct KisSeExprScript::Private {
0021     QString script;
0022     QByteArray data;
0023 };
0024 
0025 KisSeExprScript::KisSeExprScript(const QString &filename)
0026     : KoResource(filename)
0027     , d(new Private)
0028 {
0029     setName(name().replace("_", " "));
0030     if (name().endsWith(defaultFileExtension())) {
0031         const QFileInfo f(name());
0032         setName(f.completeBaseName());
0033     }
0034 }
0035 
0036 KisSeExprScript::KisSeExprScript(const QImage &image, const QString &script, const QString &name, const QString &folderName)
0037     : KoResource(QString())
0038     , d(new Private)
0039 {
0040     setScript(script);
0041     setImage(image);
0042     setName(name);
0043 
0044     QFileInfo fileInfo(folderName + QDir::separator() + name + defaultFileExtension());
0045 
0046     int i = 1;
0047     while (fileInfo.exists()) {
0048         fileInfo.setFile(folderName + QDir::separator() + name + QString::number(i) + defaultFileExtension());
0049         i++;
0050     }
0051 
0052     setFilename(fileInfo.filePath());
0053 }
0054 
0055 KisSeExprScript::KisSeExprScript(KisSeExprScript *rhs)
0056     : KisSeExprScript(*rhs)
0057 {
0058 }
0059 
0060 KisSeExprScript::KisSeExprScript(const KisSeExprScript &rhs)
0061     : KoResource(rhs)
0062     , d(new Private)
0063 {
0064     KIS_SAFE_ASSERT_RECOVER_NOOP(isDirty() == rhs.isDirty());
0065     // only valid if we could clone the settings
0066     setScript(rhs.script());
0067     setValid(rhs.valid());
0068 }
0069 
0070 KisSeExprScript::~KisSeExprScript()
0071 {
0072     delete d;
0073 }
0074 
0075 bool KisSeExprScript::loadFromDevice(QIODevice *dev, KisResourcesInterfaceSP resourcesInterface)
0076 {
0077     Q_UNUSED(resourcesInterface);
0078 
0079     if (!dev->isOpen())
0080         dev->open(QIODevice::ReadOnly);
0081 
0082     d->data = dev->readAll();
0083 
0084     // TODO: test
0085     KIS_ASSERT_RECOVER_RETURN_VALUE(d->data.size() != 0, false);
0086 
0087     if (filename().isNull()) {
0088         warnFlake << "Cannot load SeExpr script" << name() << ", there is no filename set";
0089         return false;
0090     }
0091 
0092     if (d->data.isNull()) {
0093         QFile file(filename());
0094         if (file.size() == 0) {
0095             warnFlake << "Cannot load SeExpr script" << name() << "there is no data available";
0096             return false;
0097         }
0098 
0099         file.open(QIODevice::ReadOnly);
0100         d->data = file.readAll();
0101         file.close();
0102     }
0103 
0104     QBuffer buf(&d->data);
0105     buf.open(QBuffer::ReadOnly);
0106 
0107     QScopedPointer<KoStore> store(KoStore::createStore(&buf, KoStore::Read, "application/x-krita-seexpr-script", KoStore::Zip));
0108     if (!store || store->bad())
0109         return false;
0110 
0111     bool storeOpened = store->open("script.se");
0112     if (!storeOpened) {
0113         return false;
0114     }
0115 
0116     d->script = QString(store->read(store->size()));
0117     store->close();
0118 
0119     if (store->open("preview.png")) {
0120         KoStoreDevice previewDev(store.data());
0121         previewDev.open(QIODevice::ReadOnly);
0122 
0123         QImage preview = QImage();
0124         preview.load(&previewDev, "PNG");
0125         setImage(preview);
0126 
0127         (void)store->close();
0128     }
0129 
0130     buf.close();
0131 
0132     setValid(true);
0133     setDirty(false);
0134 
0135     return true;
0136 }
0137 
0138 bool KisSeExprScript::saveToDevice(QIODevice *dev) const
0139 {
0140     KoStore *store(KoStore::createStore(dev, KoStore::Write, "application/x-krita-seexpr-script", KoStore::Zip));
0141     if (!store || store->bad())
0142         return false;
0143 
0144     if (!store->open("script.se")) {
0145         return false;
0146     }
0147 
0148     KoStoreDevice storeDev(store);
0149     storeDev.open(QIODevice::WriteOnly);
0150 
0151     storeDev.write(d->script.toUtf8());
0152 
0153     if (!store->close()) {
0154         return false;
0155     }
0156 
0157     if (!store->open("preview.png")) {
0158         return false;
0159     }
0160 
0161     KoStoreDevice previewDev(store);
0162     previewDev.open(QIODevice::WriteOnly);
0163 
0164     image().save(&previewDev, "PNG");
0165     if (!store->close()) {
0166         return false;
0167     }
0168 
0169     return store->finalize();
0170 }
0171 
0172 QPair<QString, QString> KisSeExprScript::resourceType() const
0173 {
0174     return QPair<QString, QString>(ResourceType::SeExprScripts, "");
0175 }
0176 
0177 QString KisSeExprScript::defaultFileExtension() const
0178 {
0179     return QString(".kse");
0180 }
0181 
0182 QString KisSeExprScript::script() const
0183 {
0184     return d->script;
0185 }
0186 
0187 void KisSeExprScript::setScript(const QString &script)
0188 {
0189     d->script = script;
0190 }
0191 
0192 KoResourceSP KisSeExprScript::clone() const
0193 {
0194     return KoResourceSP(new KisSeExprScript(*this));
0195 }
0196 
0197 QString KisSeExprScript::name() const
0198 {
0199     return KoResource::name().replace("_", " ");
0200 }