diff --git a/libs/flake/resources/KoSvgSymbolCollectionResource.cpp b/libs/flake/resources/KoSvgSymbolCollectionResource.cpp index 04b7ff6a22..4b3f0d8c00 100644 --- a/libs/flake/resources/KoSvgSymbolCollectionResource.cpp +++ b/libs/flake/resources/KoSvgSymbolCollectionResource.cpp @@ -1,267 +1,277 @@ /* This file is part of the KDE project Copyright (c) 2017 L. E. Segovia This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include "kis_debug.h" #include #include #include #include #include #include +#include +#include #include void paintGroup(KoShapeGroup *group, QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &paintContext) { QList shapes = group->shapes(); std::sort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex); Q_FOREACH (KoShape *child, shapes) { // we paint recursively here, so we do not have to check recursively for visibility if (!child->isVisible(false)) continue; KoShapeGroup *childGroup = dynamic_cast(child); if (childGroup) { paintGroup(childGroup, painter, converter, paintContext); } else { painter.save(); KoShapeManager::renderSingleShape(child, painter, converter, paintContext); painter.restore(); } } } QImage KoSvgSymbol::icon() { KoShapeGroup *group = dynamic_cast(shape); KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(group, QImage()); QRectF rc = group->boundingRect().normalized(); QImage image(rc.width(), rc.height(), QImage::Format_ARGB32_Premultiplied); QPainter gc(&image); image.fill(Qt::gray); KoViewConverter vc; KoShapePaintingContext ctx; // debugFlake << "Going to render. Original bounding rect:" << group->boundingRect() // << "Normalized: " << rc // << "Scale W" << 256 / rc.width() << "Scale H" << 256 / rc.height(); gc.translate(-rc.x(), -rc.y()); paintGroup(group, gc, vc, ctx); gc.end(); image = image.scaled(128, 128, Qt::KeepAspectRatio); return image; } struct KoSvgSymbolCollectionResource::Private { QVector symbols; QString title; QString description; }; KoSvgSymbolCollectionResource::KoSvgSymbolCollectionResource(const QString& filename) : KoResource(filename) , d(new Private()) { } KoSvgSymbolCollectionResource::KoSvgSymbolCollectionResource() : KoResource(QString()) , d(new Private()) { } KoSvgSymbolCollectionResource::KoSvgSymbolCollectionResource(const KoSvgSymbolCollectionResource& rhs) : KoResource(QString()) , d(new Private()) { *this = rhs; } KoSvgSymbolCollectionResource &KoSvgSymbolCollectionResource::operator=(const KoSvgSymbolCollectionResource &rhs) { if (*this != rhs) { d->symbols = rhs.d->symbols; d->title = rhs.d->title; d->description = rhs.d->description; } return *this; } KoResourceSP KoSvgSymbolCollectionResource::clone() const { return KoResourceSP(new KoSvgSymbolCollectionResource(*this)); } KoSvgSymbolCollectionResource::~KoSvgSymbolCollectionResource() { } bool KoSvgSymbolCollectionResource::load() { QFile file(filename()); if (file.size() == 0) return false; if (!file.open(QIODevice::ReadOnly)) { return false; } bool res = loadFromDevice(&file); file.close(); return res; } bool KoSvgSymbolCollectionResource::loadFromDevice(QIODevice *dev) { - if (!dev->isOpen()) dev->open(QIODevice::ReadOnly); + if (!dev->isOpen()) { + dev->open(QIODevice::ReadOnly); + } + + QByteArray ba = dev->readAll(); + KoHashGenerator *hashGenerator = KoHashGeneratorProvider::instance()->getGenerator("MD5"); + setMD5(hashGenerator->generateHash(ba)); + + dev->seek(0); QString errorMsg; int errorLine = 0; int errorColumn; KoXmlDocument doc = SvgParser::createDocumentFromSvg(dev, &errorMsg, &errorLine, &errorColumn); if (doc.isNull()) { errKrita << "Parsing error in " << filename() << "! Aborting!" << endl << " In line: " << errorLine << ", column: " << errorColumn << endl << " Error message: " << errorMsg << endl; errKrita << i18n("Parsing error in the main document at line %1, column %2\nError message: %3" , errorLine , errorColumn , errorMsg); return false; } KoDocumentResourceManager manager; SvgParser parser(&manager); parser.setResolution(QRectF(0,0,100,100), 72); // initialize with default values QSizeF fragmentSize; // We're not interested in the shapes themselves qDeleteAll(parser.parseSvg(doc.documentElement(), &fragmentSize)); d->symbols = parser.takeSymbols(); // debugFlake << "Loaded" << filename() << "\n\t" // << "Title" << parser.documentTitle() << "\n\t" // << "Description" << parser.documentDescription() // << "\n\tgot" << d->symbols.size() << ResourceType::Symbols // << d->symbols[0]->shape->outlineRect() // << d->symbols[0]->shape->size(); d->title = parser.documentTitle(); setName(d->title); d->description = parser.documentDescription(); if (d->symbols.size() < 1) { setValid(false); return false; } setValid(true); setImage(d->symbols[0]->icon()); return true; } bool KoSvgSymbolCollectionResource::save() { QFile file(filename()); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { return false; } saveToDevice(&file); file.close(); return true; } bool KoSvgSymbolCollectionResource::saveToDevice(QIODevice *dev) const { bool res = false; // XXX if (res) { KoResource::saveToDevice(dev); } return res; } QString KoSvgSymbolCollectionResource::defaultFileExtension() const { return QString(".svg"); } QString KoSvgSymbolCollectionResource::title() const { return d->title; } QString KoSvgSymbolCollectionResource::description() const { return d->description; } QString KoSvgSymbolCollectionResource::creator() const { return ""; } QString KoSvgSymbolCollectionResource::rights() const { return ""; } QString KoSvgSymbolCollectionResource::language() const { return ""; } QStringList KoSvgSymbolCollectionResource::subjects() const { return QStringList(); } QString KoSvgSymbolCollectionResource::license() const { return ""; } QStringList KoSvgSymbolCollectionResource::permits() const { return QStringList(); } QVector KoSvgSymbolCollectionResource::symbols() const { return d->symbols; } diff --git a/libs/resources/KoResource.cpp b/libs/resources/KoResource.cpp index 1c5f7c84d2..8a3eee80bf 100644 --- a/libs/resources/KoResource.cpp +++ b/libs/resources/KoResource.cpp @@ -1,223 +1,223 @@ /* This file is part of the KDE project Copyright (c) 2003 Patrick Julien Copyright (c) 2005 Boudewijn Rempt Copyright (c) 2007 Jan Hambrecht This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include "KoHashGenerator.h" #include "KoHashGeneratorProvider.h" struct Q_DECL_HIDDEN KoResource::Private { + int version {0}; + int resourceId {-1}; + bool valid {false}; + bool permanent {false}; + bool dirty {false}; QString name; QString filename; - bool valid {false}; + QString storageLocation; QByteArray md5; QImage image; - bool permanent {false}; - int resourceId {-1}; - QString storageLocation; - bool dirty; QMap metadata; - int version {0}; }; KoResource::KoResource(const QString& filename) : d(new Private) { d->filename = filename; } KoResource::~KoResource() { delete d; } KoResource::KoResource(const KoResource &rhs) : d(new Private) { *this = rhs; } KoResource &KoResource::operator=(const KoResource &rhs) { if (this != &rhs) { d->name = rhs.d->name; d->filename= rhs.d->filename; d->valid = rhs.d->valid; d->md5 = rhs.d->md5; d->image = rhs.d->image; d->permanent = rhs.d->permanent; d->resourceId = rhs.d->resourceId; d->storageLocation = rhs.d->storageLocation; d->dirty = rhs.d->dirty; d->metadata = rhs.d->metadata; d->version = rhs.d->version; } return *this; } bool KoResource::saveToDevice(QIODevice *dev) const { Q_UNUSED(dev) d->md5 = QByteArray(); return true; } QImage KoResource::image() const { return d->image; } void KoResource::setImage(const QImage &image) { d->image = image; } QByteArray KoResource::md5() const { if (d->md5.isEmpty()) { const_cast(this)->setMD5(generateMD5()); } return d->md5; } void KoResource::setMD5(const QByteArray &md5) { d->md5 = md5; } QByteArray KoResource::generateMD5() const { KoHashGenerator *hashGenerator = KoHashGeneratorProvider::instance()->getGenerator("MD5"); QByteArray hash; QByteArray ba; QBuffer buf(&ba); buf.open(QBuffer::WriteOnly); if (saveToDevice(&buf)) { buf.close(); hash = hashGenerator->generateHash(ba); } else { qWarning() << "Could not create md5sum for resource" << d->filename; } return hash; } QString KoResource::filename() const { return d->filename; } void KoResource::setFilename(const QString& filename) { d->filename = filename; } QString KoResource::name() const { return (!d->name.isEmpty() ? d->name : filename()); } void KoResource::setName(const QString& name) { d->name = name; } bool KoResource::valid() const { return d->valid; } void KoResource::setValid(bool valid) { d->valid = valid; } QString KoResource::defaultFileExtension() const { return QString(); } bool KoResource::permanent() const { return d->permanent; } void KoResource::setPermanent(bool permanent) { d->permanent = permanent; } int KoResource::resourceId() const { return d->resourceId; } QString KoResource::storageLocation() const { return d->storageLocation; } void KoResource::setDirty(bool value) { d->dirty = value; } bool KoResource::isDirty() const { return d->dirty; } void KoResource::addMetaData(QString key, QVariant value) { d->metadata.insert(key, value); } QMap KoResource::metadata() const { return d->metadata; } int KoResource::version() const { return d->version; } void KoResource::setVersion(int version) { d->version = version; } void KoResource::setResourceId(int id) { d->resourceId = id; } void KoResource::setStorageLocation(const QString &location) { d->storageLocation = location; } diff --git a/libs/resources/sql/create_versioned_resources.sql b/libs/resources/sql/create_versioned_resources.sql index 9c8f213dc5..1a5691dfce 100644 --- a/libs/resources/sql/create_versioned_resources.sql +++ b/libs/resources/sql/create_versioned_resources.sql @@ -1,11 +1,11 @@ CREATE TABLE IF NOT EXISTS versioned_resources ( id INTEGER PRIMARY KEY , resource_id INTEGER , storage_id INTEGER , version INTEGER , location TEXT NOT NULL -, md5sum TEXT +, md5sum TEXT NOT NULL , timestamp INTEGER , FOREIGN KEY(resource_id) REFERENCES resources(id) , FOREIGN KEY(storage_id) REFERENCES storages(id) );