File indexing completed on 2025-03-09 04:10:27

0001 /*
0002  *  SPDX-FileCopyrightText: 2018 Jouni Pentikäinen <joupent@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #include "KisReferenceImageCollection.h"
0007 
0008 #include <QIODevice>
0009 #include <QMessageBox>
0010 
0011 #include <libs/store/KoStore.h>
0012 #include <KisReferenceImage.h>
0013 #include <libs/store/KoStoreDevice.h>
0014 
0015 const QString METADATA_FILE = "reference_images.xml";
0016 
0017 KisReferenceImageCollection::KisReferenceImageCollection(const QVector<KisReferenceImage *> &references)
0018     : references(references)
0019 {}
0020 
0021 const QVector<KisReferenceImage*> &KisReferenceImageCollection::referenceImages() const
0022 {
0023     return references;
0024 }
0025 
0026 bool KisReferenceImageCollection::save(QIODevice *io)
0027 {
0028     QScopedPointer<KoStore> store(KoStore::createStore(io, KoStore::Write, "application/x-krita-reference-images]", KoStore::Zip));
0029     if (store.isNull()) return false;
0030 
0031     QDomDocument doc;
0032     QDomElement root = doc.createElement("referenceimages");
0033     doc.insertBefore(root, QDomNode());
0034 
0035     std::sort(references.begin(), references.end(), KoShape::compareShapeZIndex);
0036 
0037     int nextId = 0;
0038     Q_FOREACH(KisReferenceImage *reference, references) {
0039         reference->saveXml(doc, root, nextId++);
0040 
0041         if (reference->embed()) {
0042             bool ok = reference->saveImage(store.data());
0043             if (!ok) return false;
0044         }
0045     }
0046 
0047     if (!store->open(METADATA_FILE)) {
0048         return false;
0049     }
0050 
0051     KoStoreDevice xmlDev(store.data());
0052     xmlDev.write(doc.toByteArray());
0053     xmlDev.close();
0054     store->close();
0055 
0056     return true;
0057 }
0058 
0059 bool KisReferenceImageCollection::load(QIODevice *io)
0060 {
0061     QScopedPointer<KoStore> store(KoStore::createStore(io, KoStore::Read, "application/x-krita-reference-images", KoStore::Zip));
0062     if (!store || store->bad()) {
0063         return false;
0064     }
0065 
0066     if (!store->hasFile(METADATA_FILE) || !store->open(METADATA_FILE)) {
0067         return false;
0068     }
0069 
0070     QByteArray xml = store->device()->readAll();
0071     store->close();
0072 
0073     QDomDocument doc;
0074     doc.setContent(xml);
0075     QDomElement root = doc.documentElement();
0076 
0077     QStringList failures;
0078 
0079     QDomElement element = root.firstChildElement("referenceimage");
0080     while (!element.isNull()) {
0081         KisReferenceImage *reference = KisReferenceImage::fromXml(element);
0082 
0083         if (reference->loadImage(store.data())) {
0084             references.append(reference);
0085         } else {
0086             failures << (reference->embed() ? reference->internalFile() : reference->filename());
0087             delete reference;
0088         }
0089         element = element.nextSiblingElement("referenceimage");
0090     }
0091 
0092     if (!failures.isEmpty()) {
0093         QMessageBox::warning(
0094                 0,
0095                 i18nc("@title:window", "Krita"),
0096                 i18n("The following reference images could not be loaded:\n%1", failures.join('\n')),
0097                 QMessageBox::Ok, QMessageBox::Ok
0098         );
0099 
0100     }
0101 
0102     return true;
0103 }