diff --git a/src/acbf/AcbfDocument.h b/src/acbf/AcbfBinary.h copy from src/acbf/AcbfDocument.h copy to src/acbf/AcbfBinary.h --- a/src/acbf/AcbfDocument.h +++ b/src/acbf/AcbfBinary.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Dan Leinir Turthra Jensen + * Copyright (C) 2017 Jesse Pullinen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,41 +19,41 @@ * */ -#ifndef ACBFDOCUMENT_H -#define ACBFDOCUMENT_H +#ifndef ACBFBINARY_H +#define ACBFBINARY_H #include + #include "acbf_export.h" +class QXmlStreamReader; +class QXmlStreamWriter; + namespace AdvancedComicBookFormat { -class Metadata; -class Body; -// class References; -// class Data; -// class Stylesheet; -class ACBF_EXPORT Document : public QObject +class Data; +class ACBF_EXPORT Binary : public QObject { Q_OBJECT - Q_PROPERTY(Metadata* metaData READ metaData NOTIFY metaDataChanged) public: - explicit Document(QObject* parent = 0); - virtual ~Document(); + explicit Binary(Data* parent = 0); + virtual ~Binary(); + + void toXml(QXmlStreamWriter *writer); + bool fromXml(QXmlStreamReader *xmlReader); - QString toXml(); - bool fromXml(QString xmlDocument); + QString id(); + void setId(QString newId); - Metadata* metaData(); - Q_SIGNAL void metaDataChanged(); + QString contentType(); + void setContentType(QString newContentType); - Body* body(); - // References* references(); - // Data* data(); - // Stylesheet* stylesheet(); + QByteArray data(); + void setData(QByteArray newData); private: class Private; Private* d; }; } -#endif//ACBFDOCUMENT_H +#endif // ACBFBINARY_H diff --git a/src/acbf/AcbfBinary.cpp b/src/acbf/AcbfBinary.cpp new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfBinary.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2017 Jesse Pullinen + * + * 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) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * 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, see . + * + */ + +#include "AcbfBinary.h" + +#include +#include +#include +#include + +#include "AcbfData.h" + +using namespace AdvancedComicBookFormat; + +class Binary::Private { +public: + Private() {} + QString id; + QString contentType; + QByteArray data; +}; + +Binary::Binary(Data* parent) + : QObject(parent) + , d(new Private) +{ + qRegisterMetaType("Binary*"); +} + +Binary::~Binary() +{ + delete d; +} + +void Binary::toXml(QXmlStreamWriter* writer) +{ + writer->writeStartElement("binary"); + + writer->writeAttribute("id", id()); + writer->writeAttribute("contentType", contentType()); + writer->writeCharacters(QString::fromLatin1(data().toBase64())); + + writer->writeEndElement(); +} + +bool Binary::fromXml(QXmlStreamReader* xmlReader) +{ + setId(xmlReader->attributes().value("id").toString()); + setContentType(xmlReader->attributes().value("content-type").toString()); + setData(QByteArray::fromBase64(xmlReader->readElementText().toLatin1())); + + return !xmlReader->hasError(); +} + +QString Binary::id() +{ + return d->id; +} + +void Binary::setId(QString newId) +{ + d->id = newId; +} + +QString Binary::contentType() +{ + return d->contentType; +} + +void Binary::setContentType(QString newContentType) +{ + d->contentType = newContentType; +} + +QByteArray Binary::data() +{ + return d->data; +} + +void Binary::setData(QByteArray newData) +{ + d->data = newData; +} diff --git a/src/acbf/AcbfDocument.h b/src/acbf/AcbfData.h copy from src/acbf/AcbfDocument.h copy to src/acbf/AcbfData.h --- a/src/acbf/AcbfDocument.h +++ b/src/acbf/AcbfData.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Dan Leinir Turthra Jensen + * Copyright (C) 2017 Jesse Pullinen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,41 +19,32 @@ * */ -#ifndef ACBFDOCUMENT_H -#define ACBFDOCUMENT_H +#ifndef ACBFDATA_H +#define ACBFDATA_H #include -#include "acbf_export.h" +#include + +#include "AcbfDocument.h" +#include "AcbfBinary.h" namespace AdvancedComicBookFormat { -class Metadata; -class Body; -// class References; -// class Data; -// class Stylesheet; -class ACBF_EXPORT Document : public QObject +class ACBF_EXPORT Data : public QObject { Q_OBJECT - Q_PROPERTY(Metadata* metaData READ metaData NOTIFY metaDataChanged) public: - explicit Document(QObject* parent = 0); - virtual ~Document(); - - QString toXml(); - bool fromXml(QString xmlDocument); + explicit Data(Document* parent = 0); + virtual ~Data(); - Metadata* metaData(); - Q_SIGNAL void metaDataChanged(); + void toXml(QXmlStreamWriter *writer); + bool fromXml(QXmlStreamReader *xmlReader); - Body* body(); - // References* references(); - // Data* data(); - // Stylesheet* stylesheet(); + Binary* binary(QString id); private: class Private; Private* d; }; } -#endif//ACBFDOCUMENT_H +#endif // ACBFDATA_H diff --git a/src/acbf/AcbfData.cpp b/src/acbf/AcbfData.cpp new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfData.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2017 Jesse Pullinen + * + * 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) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * 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, see . + * + */ + +#include "AcbfData.h" + +#include +#include + +using namespace AdvancedComicBookFormat; + +class Data::Private { +public: + Private() {} + QHash binaries; +}; + +Data::Data(Document* parent) + : QObject(parent) + , d(new Private) +{ + qRegisterMetaType("Data*"); +} + +Data::~Data() +{ + delete d; +} + +void Data::toXml(QXmlStreamWriter* writer) +{ + writer->writeStartElement("data"); + + Q_FOREACH(Binary* binary, d->binaries) { + binary->toXml(writer); + } + + writer->writeEndElement(); +} + +bool Data::fromXml(QXmlStreamReader* xmlReader) +{ + while(xmlReader->readNextStartElement()) + { + if(xmlReader->name() == "binary") + { + Binary* newBinary = new Binary(this); + if(!newBinary->fromXml(xmlReader)) { + return false; + } + d->binaries.insert(newBinary->id(), newBinary); + } + else + { + qWarning() << Q_FUNC_INFO << "currently unsupported subsection:" << xmlReader->name(); + xmlReader->skipCurrentElement(); + } + } + if (xmlReader->hasError()) { + qWarning() << Q_FUNC_INFO << "Failed to read ACBF XML document at token" << xmlReader->name() << "(" << xmlReader->lineNumber() << ":" << xmlReader->columnNumber() << ") The reported error was:" << xmlReader->errorString(); + } + qDebug() << Q_FUNC_INFO << "Created data with" << d->binaries.count() << "binaries"; + return !xmlReader->hasError(); +} + +Binary* Data::binary(QString id) +{ + return d->binaries.value(id); +} diff --git a/src/acbf/AcbfDocument.h b/src/acbf/AcbfDocument.h --- a/src/acbf/AcbfDocument.h +++ b/src/acbf/AcbfDocument.h @@ -30,7 +30,7 @@ class Metadata; class Body; // class References; -// class Data; +class Data; // class Stylesheet; class ACBF_EXPORT Document : public QObject { @@ -48,7 +48,7 @@ Body* body(); // References* references(); - // Data* data(); + Data* data(); // Stylesheet* stylesheet(); private: class Private; diff --git a/src/acbf/AcbfDocument.cpp b/src/acbf/AcbfDocument.cpp --- a/src/acbf/AcbfDocument.cpp +++ b/src/acbf/AcbfDocument.cpp @@ -23,6 +23,7 @@ #include "AcbfBody.h" #include "AcbfMetadata.h" #include "AcbfBookinfo.h" +#include "AcbfData.h" #include #include @@ -34,17 +35,20 @@ Private() : metaData(0) , body(0) + , data(0) {} Metadata* metaData; Body* body; + Data* data; }; Document::Document(QObject* parent) : QObject(parent) , d(new Private) { d->metaData = new Metadata(this); d->body = new Body(this); + d->data = new Data(this); } Document::~Document() @@ -89,6 +93,12 @@ break; } } + else if(xmlReader.name() == "data") + { + if(!d->data->fromXml(&xmlReader)) { + break; + } + } else { qWarning() << Q_FUNC_INFO << "currently unsupported subsection:" << xmlReader.name(); @@ -117,3 +127,8 @@ { return d->body; } + +Data * Document::data() +{ + return d->data; +} diff --git a/src/acbf/CMakeLists.txt b/src/acbf/CMakeLists.txt --- a/src/acbf/CMakeLists.txt +++ b/src/acbf/CMakeLists.txt @@ -2,9 +2,11 @@ set(acbf_SRCS AcbfAuthor.cpp + AcbfBinary.cpp AcbfBody.cpp AcbfBookinfo.cpp AcbfContentrating.cpp + AcbfData.cpp AcbfDatabaseref.cpp AcbfDocument.cpp AcbfDocumentinfo.cpp diff --git a/src/qtquick/ArchiveImageProvider.cpp b/src/qtquick/ArchiveImageProvider.cpp --- a/src/qtquick/ArchiveImageProvider.cpp +++ b/src/qtquick/ArchiveImageProvider.cpp @@ -28,6 +28,10 @@ #include #include +#include +#include +#include + class ArchiveImageProvider::Private { public: @@ -54,16 +58,39 @@ Q_UNUSED(size) Q_UNUSED(requestedSize) QImage img; - const KArchiveFile* entry = d->bookModel->archiveFile(id); - if(entry) - { - bool success = img.loadFromData(entry->data()); - if(!success) { - QIcon oops = QIcon::fromTheme("unknown"); - img = oops.pixmap(oops.availableSizes().last()).toImage(); - qDebug() << "Failed to load image with id:" << id; + bool success = false; + + /* + * In ACBF, image references starting with a '#' refer to files embedded + * in the section of the .acbf file. + * see: http://acbf.wikia.com/wiki/Body_Section_Definition#Image + */ + if (id.startsWith('#')) { + auto document = qobject_cast(d->bookModel->acbfData()); + + if (document) { + AdvancedComicBookFormat::Binary* binary = document->data()->binary(id.mid(1)); + + if (binary) { + success = img.loadFromData(binary->data()); + } } } + + if (!success) { + const KArchiveFile* entry = d->bookModel->archiveFile(id); + + if(entry) { + success = img.loadFromData(entry->data()); + } + } + + if (!success) { + QIcon oops = QIcon::fromTheme("unknown"); + img = oops.pixmap(oops.availableSizes().last()).toImage(); + qDebug() << "Failed to load image with id:" << id; + } + return img; }