diff --git a/src/acbf/AcbfAuthor.h b/src/acbf/AcbfAuthor.h --- a/src/acbf/AcbfAuthor.h +++ b/src/acbf/AcbfAuthor.h @@ -54,8 +54,6 @@ * Authors should, at minimum have a name, which is either * a nickname, or a first and lastname. * - * TODO: Authors can have multiple email and homepage entries - * according to the official xsd. */ namespace AdvancedComicBookFormat @@ -161,26 +159,37 @@ Q_INVOKABLE void setNickName(const QString& name); /** - * @return the homepage associated with this author as a QString. + * @return the homepages associated with this author as a QStringList. */ - Q_INVOKABLE QString homePage() const; + Q_INVOKABLE QStringList homePages() const; /** - * \brief Set the homepage associated with this author. + * \brief Add a homepage associated with this author. * @param homepage - the url of the homepage as a string. */ - Q_INVOKABLE void setHomePage(const QString& homepage); + Q_INVOKABLE void addHomePage(const QString& homepage); /** - * @return The email adress associated with this author as a QString. + * \brief Set the homepages associated with this author. + * @param homepages - homepages as a string. */ - Q_INVOKABLE QString email() const; + Q_INVOKABLE void setHomePages(const QStringList& homepages); + + /** + * @return The email adresses associated with this author as a QStringList. + */ + Q_INVOKABLE QStringList emails() const; /** * \brief Set the email adress associated with this author. * @param email - email as a string. */ - Q_INVOKABLE void setEmail(const QString& email); + Q_INVOKABLE void addEmail(const QString& email); + /** + * \brief Add an email adresses associated with this author. + * @param emails - email dresses as a stringlist. + */ + Q_INVOKABLE void setEmails(const QStringList& emails); private: class Private; std::unique_ptr d; diff --git a/src/acbf/AcbfAuthor.cpp b/src/acbf/AcbfAuthor.cpp --- a/src/acbf/AcbfAuthor.cpp +++ b/src/acbf/AcbfAuthor.cpp @@ -36,8 +36,8 @@ QString middleName; QString lastName; QString nickName; - QString homePage; - QString email; + QStringList homePage; + QStringList email; }; Author::Author(Metadata* parent) @@ -58,10 +58,10 @@ return QStringLiteral("%1 %2 %3").arg(d->firstName).arg(d->middleName).arg(d->lastName).simplified(); } else if(!d->email.isEmpty()) { - return d->email; + return d->email.at(0); } else if(!d->homePage.isEmpty()) { - return d->homePage; + return d->homePage.at(0); } return QLatin1String(""); } @@ -80,9 +80,13 @@ writer->writeTextElement(QStringLiteral("middle-name"), d->middleName); writer->writeTextElement(QStringLiteral("last-name"), d->lastName); writer->writeTextElement(QStringLiteral("nickname"), d->nickName); - writer->writeTextElement(QStringLiteral("home-page"), d->homePage); - writer->writeTextElement(QStringLiteral("email"), d->email); - + Q_FOREACH(const QString& url, d->homePage) { + writer->writeTextElement(QStringLiteral("home-page"), url); + } + Q_FOREACH(const QString& address, d->email) { + writer->writeTextElement(QStringLiteral("email"), address); + } + writer->writeEndElement(); } @@ -110,11 +114,11 @@ } else if(xmlReader->name() == QStringLiteral("home-page")) { - setHomePage(xmlReader->readElementText()); + addHomePage(xmlReader->readElementText()); } else if(xmlReader->name() == QStringLiteral("email")) { - setEmail(xmlReader->readElementText()); + addEmail(xmlReader->readElementText()); } else { @@ -154,6 +158,7 @@ QStringLiteral("Editor"), QStringLiteral("Assistant Editor"), // /new in 1.1/ QStringLiteral("Translator"), + QStringLiteral("Designer"), // /new in 1.2/ QStringLiteral("Other") // /new in 1.1/ }; } @@ -208,22 +213,32 @@ d->nickName = name; } -QString Author::homePage() const +QStringList Author::homePages() const { return d->homePage; } -void Author::setHomePage(const QString& homepage) +void Author::addHomePage(const QString& homepage) { - d->homePage = homepage; + d->homePage.append(homepage); } -QString Author::email() const +void Author::setHomePages(const QStringList& homepages) +{ + d->homePage = homepages; +} + +QStringList Author::emails() const { return d->email; } -void Author::setEmail(const QString& email) +void Author::addEmail(const QString& email) +{ + d->email.append(email); +} + +void Author::setEmails(const QStringList& emails) { - d->email = email; + d->email = emails; } diff --git a/src/acbf/AcbfBookinfo.h b/src/acbf/AcbfBookinfo.h --- a/src/acbf/AcbfBookinfo.h +++ b/src/acbf/AcbfBookinfo.h @@ -47,6 +47,11 @@ * * Annotations in particular are a stringlist of paragraphs. * + * The library handles retrieving title, keywords and annotation when there is no + * language defined as follows: It checks if there is an entry for "", if not, tries + * the entry for the first language object, and if that doesn't work, returns the first + * value it can find. + * * ACBF's language support is further detailed in the Language object. * * ACBF can have multiple genres, but they are limited to a list of keys, given @@ -124,10 +129,10 @@ * @param middleName - the middle name(s) of the author as a string. * @param lastName - the family name of the author. * @param nickName - the nickname of the author. - * @param homePage - a homepage url to associate with this author. - * @param email - an email adress to associate with this author. + * @param homePages - a homepage url to associate with this author. + * @param emails - an email adress to associate with this author. */ - Q_INVOKABLE void addAuthor(QString activity, QString language, QString firstName, QString middleName, QString lastName, QString nickName, QString homePage, QString email); + Q_INVOKABLE void addAuthor(QString activity, QString language, QString firstName, QString middleName, QString lastName, QString nickName, QStringList homePages, QStringList emails); /** * \brief make changes to an author in the list. * @param index - The index of this author in the author list. @@ -138,10 +143,10 @@ * @param middleName - the middle name(s) of the author as a string. * @param lastName - the family name of the author. * @param nickName - the nickname of the author. - * @param homePage - a homepage url to associate with this author. - * @param email - an email adress to associate with this author. + * @param homePages - a homepage url to associate with this author. + * @param emails - an email adress to associate with this author. */ - Q_INVOKABLE void setAuthor(int index, QString activity, QString language, QString firstName, QString middleName, QString lastName, QString nickName, QString homePage, QString email); + Q_INVOKABLE void setAuthor(int index, QString activity, QString language, QString firstName, QString middleName, QString lastName, QString nickName, QStringList homePages, QStringList emails); /** * \brief remove an author in the list. * @param index - the index of the author to remove. @@ -183,7 +188,6 @@ * @param title - the title as a QString * @param language - the language code in language code, country * code format joined by a dash (not an underscore). - * TODO: title() defaults to English when no language is given, but setTitle() does not... */ Q_INVOKABLE void setTitle(QString title, QString language = ""); @@ -279,7 +283,7 @@ QStringList keywords(QString language = ""); /** * \brief set the list of keywords for the given language. - * @param annotation - A stringlist of keywords + * @param keywords - A stringlist of keywords * @param language - The language for which to set the annotation in * language code, country code format joined by a dash (not an underscore). */ @@ -291,7 +295,7 @@ Page* coverpage(); /** * \brief set a cover page. - * @param newCover + * @param newCover A page object with the new cover. */ void setCoverpage(Page* newCover); @@ -363,6 +367,21 @@ * contentrating system. */ void removeContentRating(ContentRating* contentRating); + + /** + * @brief The reading direction for this comic for adjusting the layout. + * An ACBF 1.2 feature. + * @return QString with either ltr or rtl. + */ + QString readingDirection() const; + + /** + * @brief set the Reading direction for this comic. This indicates + * how the UI will lay out the buttons and controls. + * An ACBF 1.2 feature. + * @param readingDirection a QString with either "ltr" or "rtl". + */ + void setReadingDirection(const QString& readingDirection = "ltr"); private: class Private; std::unique_ptr d; diff --git a/src/acbf/AcbfBookinfo.cpp b/src/acbf/AcbfBookinfo.cpp --- a/src/acbf/AcbfBookinfo.cpp +++ b/src/acbf/AcbfBookinfo.cpp @@ -50,6 +50,7 @@ QList sequence; QList databaseRef; QList contentRating; + QString readingDirection; }; BookInfo::BookInfo(Metadata* parent) @@ -142,6 +143,13 @@ Q_FOREACH(ContentRating* rating, d->contentRating) { rating->toXml(writer); } + + //ACBF 1.2 + /* + writer->writeStartElement("characters"); + writer->writeCharacters(d->readingDirection); + writer->writeEndElement(); + */ writer->writeEndElement(); } @@ -236,6 +244,10 @@ newContentRating->fromXml(xmlReader); d->contentRating.append(newContentRating); } + else if(xmlReader->name() == QStringLiteral("reading-direction")) + { + setReadingDirection(xmlReader->readElementText(QXmlStreamReader::IncludeChildElements).toLower()); + } else { qWarning() << Q_FUNC_INFO << "currently unsupported subsection:" << xmlReader->name(); @@ -245,7 +257,7 @@ 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 book information for the book with the titles" << d->title.values();; + qDebug() << Q_FUNC_INFO << "Created book information for the book with the titles" << d->title.values(); return !xmlReader->hasError(); } @@ -268,7 +280,7 @@ return d->author.at(index); } -void BookInfo::addAuthor(QString activity, QString language, QString firstName, QString middleName, QString lastName, QString nickName, QString homePage, QString email) +void BookInfo::addAuthor(QString activity, QString language, QString firstName, QString middleName, QString lastName, QString nickName, QStringList homePages, QStringList emails) { Author* author = new Author(metadata()); author->setActivity(activity); @@ -277,13 +289,13 @@ author->setMiddleName(middleName); author->setLastName(lastName); author->setNickName(nickName); - author->setHomePage(homePage); - author->setEmail(email); + author->setHomePages(homePages); + author->setEmails(emails); d->author.append(author); emit authorsChanged(); } -void BookInfo::setAuthor(int index, QString activity, QString language, QString firstName, QString middleName, QString lastName, QString nickName, QString homePage, QString email) +void BookInfo::setAuthor(int index, QString activity, QString language, QString firstName, QString middleName, QString lastName, QString nickName, QStringList homePages, QStringList emails) { Author* author = d->author.at(index); author->setActivity(activity); @@ -292,8 +304,8 @@ author->setMiddleName(middleName); author->setLastName(lastName); author->setNickName(nickName); - author->setHomePage(homePage); - author->setEmail(email); + author->setHomePages(homePages); + author->setEmails(emails); emit authorsChanged(); } @@ -327,10 +339,24 @@ QString BookInfo::title(QString language) { - if(language.isEmpty()) { - language = "en"; + if (d->title.count()==0) { + return ""; + } + if (!d->title.keys().contains(language)) { + language = ""; } - return d->title.value(language); + + if(language.isEmpty() && d->title[language].isEmpty() && d->languages.count()>0) { + language = d->languages.at(0)->language(); + } + + QString title = d->title.value(language); + + if (title.isEmpty()) { + title = d->title.values().at(0); + } + + return title; } void BookInfo::setTitle(QString title, QString language) @@ -381,31 +407,32 @@ QStringList BookInfo::availableGenres() { return { - QStringLiteral("science_fiction"), - QStringLiteral("fantasy"), + QStringLiteral("adult"), QStringLiteral("adventure"), - QStringLiteral("horror"), - QStringLiteral("mystery"), + QStringLiteral("alternative"), // (abstract, underground ...) + QStringLiteral("artbook"), // 1.2 + QStringLiteral("biography"), // (biographical comics) + QStringLiteral("caricature"), + QStringLiteral("children"), + QStringLiteral("computer"), // (computers related) QStringLiteral("crime"), - QStringLiteral("military"), // (war ...) - QStringLiteral("real_life"), - QStringLiteral("superhero"), // (e.g. Superman, Spiderman … or Super Villains) + QStringLiteral("education"), // (education and science) + QStringLiteral("fantasy"), + QStringLiteral("history"), // (historical comics) + QStringLiteral("horror"), QStringLiteral("humor"), - QStringLiteral("western"), QStringLiteral("manga"), + QStringLiteral("military"), // (war ...) + QStringLiteral("mystery"), + QStringLiteral("non-fiction"), QStringLiteral("politics"), - QStringLiteral("caricature"), - QStringLiteral("sports"), - QStringLiteral("history"), // (historical comics) - QStringLiteral("biography"), // (biographical comics) - QStringLiteral("education"), // (education and science) - QStringLiteral("computer"), // (computers related) + QStringLiteral("real_life"), QStringLiteral("religion"), QStringLiteral("romance"), - QStringLiteral("children"), - QStringLiteral("non-fiction"), - QStringLiteral("adult"), - QStringLiteral("alternative"), // (abstract, underground ...) + QStringLiteral("science_fiction"), + QStringLiteral("sports"), + QStringLiteral("superhero"), // (e.g. Superman, Spiderman … or Super Villains) + QStringLiteral("western"), QStringLiteral("other") }; } @@ -440,7 +467,21 @@ QStringList BookInfo::annotation(QString language) { - return d->annotation.value(language); + if (!d->annotation.keys().contains(language)) { + language = ""; + } + + if(language.isEmpty() && d->annotation.value(language).count()==0) { + language = d->languages.at(0)->language(); + } + + QStringList annotation = d->annotation.value(language); + + if (annotation.count()==0) { + annotation = d->annotation.values().at(0); + } + + return annotation; } void BookInfo::setAnnotation(QStringList annotation, QString language) @@ -455,7 +496,21 @@ QStringList BookInfo::keywords(QString language) { - return d->keywords.value(language); + if (!d->keywords.keys().contains(language)) { + language = ""; + } + + if(language.isEmpty() && d->keywords.value(language).count()==0) { + language = d->languages.at(0)->language(); + } + + QStringList keywords = d->keywords.value(language); + + if (keywords.count()==0) { + keywords = d->keywords.values().at(0); + } + + return keywords; } void BookInfo::setKeywords(QStringList keywords, QString language) @@ -508,6 +563,7 @@ return d->databaseRef; } + void BookInfo::addDatabaseRef(DatabaseRef* databaseRef) { d->databaseRef.append(databaseRef); @@ -532,3 +588,14 @@ { d->contentRating.removeAll(contentRating); } +QString BookInfo::readingDirection() const +{ + return d->readingDirection; +} + +void BookInfo::setReadingDirection(const QString& readingDirection) { + if (readingDirection == "ltr" || + readingDirection == "rtl") { + d->readingDirection = readingDirection; + } +} diff --git a/src/acbf/AcbfDocument.h b/src/acbf/AcbfDocument.h --- a/src/acbf/AcbfDocument.h +++ b/src/acbf/AcbfDocument.h @@ -47,9 +47,9 @@ { class Metadata; class Body; -// class References; +class References; class Data; -// class Stylesheet; +class StyleSheet; class ACBF_EXPORT Document : public QObject { Q_OBJECT @@ -81,12 +81,24 @@ * @returns the Body object. */ Body* body() const; - // References* references(); + + /** + * @brief The reference section. + * + * @return a References object with the references. + */ + References* references() const; /** * @returns the Data object. */ Data* data() const; - // Stylesheet* stylesheet(); + + /** + * @brief The style section, which contains a css stylesheet. + * + * @return A StyleSheet object with the css. + */ + StyleSheet* styleSheet() const; private: class Private; std::unique_ptr d; diff --git a/src/acbf/AcbfDocument.cpp b/src/acbf/AcbfDocument.cpp --- a/src/acbf/AcbfDocument.cpp +++ b/src/acbf/AcbfDocument.cpp @@ -24,6 +24,8 @@ #include "AcbfMetadata.h" #include "AcbfBookinfo.h" #include "AcbfData.h" +#include "AcbfReferences.h" +#include "AcbfStyleSheet.h" #include #include @@ -40,6 +42,9 @@ Metadata* metaData; Body* body; Data* data; + References* references; + StyleSheet* cssStyleSheet; + }; Document::Document(QObject* parent) @@ -49,6 +54,8 @@ d->metaData = new Metadata(this); d->body = new Body(this); d->data = new Data(this); + d->references = new References(this); + d->cssStyleSheet = new StyleSheet(this); } Document::~Document() = default; @@ -79,6 +86,7 @@ || xmlReader.namespaceUri().startsWith(QStringLiteral("http://www.acbf.info/xml/acbf/")) )) { + qDebug()<< xmlReader.documentEncoding().toString(); while(xmlReader.readNextStartElement()) { if(xmlReader.name() == QStringLiteral("meta-data")) @@ -99,6 +107,18 @@ break; } } + else if(xmlReader.name() == QStringLiteral("references")) + { + if(!d->references->fromXml(&xmlReader)) { + break; + } + } + else if(xmlReader.name() == QStringLiteral("style")) + { + if(!d->cssStyleSheet->fromXml(&xmlReader)) { + break; + } + } else { qWarning() << Q_FUNC_INFO << "currently unsupported subsection:" << xmlReader.name(); @@ -132,3 +152,13 @@ { return d->data; } + +References * Document::references() const +{ + return d->references; +} + +StyleSheet * Document::styleSheet() const +{ + return d->cssStyleSheet; +} diff --git a/src/acbf/AcbfDocumentinfo.h b/src/acbf/AcbfDocumentinfo.h --- a/src/acbf/AcbfDocumentinfo.h +++ b/src/acbf/AcbfDocumentinfo.h @@ -106,15 +106,14 @@ void setId(const QString& id); /** - * @return the version of this document. + * @return the version of this document as a float. */ - QString version() const; + float version() const; /** * \brief set the version of this document - * @param version - the version as a string. - * TODO: The official XSD requires a floating point number here. + * @param version - the version as a floating point number. */ - void setVersion(const QString& version); + void setVersion(const float& version); /** * @return a list of history entries as a stringlist. diff --git a/src/acbf/AcbfDocumentinfo.cpp b/src/acbf/AcbfDocumentinfo.cpp --- a/src/acbf/AcbfDocumentinfo.cpp +++ b/src/acbf/AcbfDocumentinfo.cpp @@ -35,7 +35,7 @@ QDate creationDate; QStringList source; QString id; - QString version; + float version; QStringList history; }; @@ -78,7 +78,7 @@ writer->writeEndElement(); writer->writeStartElement(QStringLiteral("version")); - writer->writeCharacters(d->version); + writer->writeCharacters(QString::number(d->version)); writer->writeEndElement(); writer->writeStartElement(QStringLiteral("history")); @@ -131,7 +131,7 @@ } else if(xmlReader->name() == QStringLiteral("version")) { - setVersion(xmlReader->readElementText()); + setVersion(QString(xmlReader->readElementText()).toFloat()); } else if(xmlReader->name() == QStringLiteral("history")) { @@ -202,12 +202,12 @@ d->id = id; } -QString DocumentInfo::version() const +float DocumentInfo::version() const { return d->version; } -void DocumentInfo::setVersion(const QString& version) +void DocumentInfo::setVersion(const float& version) { d->version = version; } diff --git a/src/acbf/AcbfFrame.h b/src/acbf/AcbfFrame.h new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfFrame.h @@ -0,0 +1,116 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 . + * + */ + +#ifndef ACBFFRAME_H +#define ACBFFRAME_H + +#include +#include + +#include "AcbfPage.h" + +#include +/** + * \brief a Class to handle comic panels. + * + * Frames are a polygon of points, which describe + * a panel on a comic book page image in pixels. + * + * This can be used to give improved navigation on + * smaller screens. + * + * Frames also have a background color which can be used + * to enhance the reading experience by setting the background + * color to the frame color. + */ +namespace AdvancedComicBookFormat +{ +class ACBF_EXPORT Frame : public QObject +{ + Q_OBJECT + +public: + explicit Frame(Page* parent = nullptr); + ~Frame() override; + + /** + * \brief Write the textarea into the xml writer. + */ + void toXml(QXmlStreamWriter* writer); + /** + * \brief load a textarea element into this object. + * @return True if the xmlReader encountered no errors. + */ + bool fromXml(QXmlStreamReader *xmlReader); + + /** + * @return a list of points that encompasses the textarea. + */ + QList points() const; + /** + * @param index - the index of the desired point. + * @return a point for an index. + */ + QPoint point(int index) const; + /** + * @param point - a point from the points list. + * @return the index of the given point. + */ + int pointIndex(const QPoint& point) const; + + /** + * \brief add a point to the points list. + * @param point - the point to add. Coordinates should be in pixels. + * @param index - the index to add it at. If afterIndex is larger than zero, + * the insertion will happen at that index + */ + void addPoint(const QPoint& point, int index = -1); + /** + * \brief remove a point from the list. + * @param point - point to remove from the list. + */ + void removePoint(const QPoint& point); + /** + * \brief Swap two points in the list. + * @param swapThis - the first points to swap. + * @param withThis - the second points to swap. + */ + bool swapPoints(const QPoint& swapThis, const QPoint& withThis); + /** + * @return the background color as a QString. + * + * It should be an 8bit per channel rgb hexcode. + */ + QString bgcolor() const; + /** + * \brief set the background color. + * + * @param newColor - a String with an 8bit per channel rgb hexcode (#ff00ff, or the like) + */ + void setBgcolor(const QString& newColor = QString()); + +private: + class Private; + std::unique_ptr d; +}; +} + +#endif // ACBFFRAME_H diff --git a/src/acbf/AcbfFrame.cpp b/src/acbf/AcbfFrame.cpp new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfFrame.cpp @@ -0,0 +1,135 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 "AcbfFrame.h" +#include +#include + +using namespace AdvancedComicBookFormat; + +class Frame::Private +{ +public: + Private() + {} + QString bgcolor; + QList points; +}; + +Frame::Frame(Page* parent) + : QObject(parent) + , d(new Private) +{ +} + +Frame::~Frame() = default; + +void Frame::toXml(QXmlStreamWriter* writer) { + writer->writeStartElement(QStringLiteral("frame")); + + QStringList points; + Q_FOREACH(const QPoint& point, d->points) { + points << QStringLiteral("%1,%2").arg(QString::number(point.x())).arg(QString::number(point.y())); + } + writer->writeAttribute(QStringLiteral("points"), points.join(' ')); + if(!d->bgcolor.isEmpty()) { + writer->writeAttribute(QStringLiteral("bgcolor"), d->bgcolor); + } + writer->writeEndElement(); +} + +bool Frame::fromXml(QXmlStreamReader *xmlReader) +{ + setBgcolor(xmlReader->attributes().value(QStringLiteral("bgcolor")).toString()); + + QStringList points = xmlReader->attributes().value(QStringLiteral("points")).toString().split(' '); + + Q_FOREACH(const QString& point, points) { + QStringList elements = point.split(','); + if(elements.length() == 2) + { + addPoint(QPoint(elements.at(0).toInt(), elements.at(1).toInt())); + } + else + { + qWarning() << "Failed to construct one of the points for a frame. Attempted to handle the point" << point << "in the data" << points; + return false; + } + } + + 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 a frame with " << points.count() << "points"; + + return !xmlReader->hasError(); +} + +QList Frame::points() const +{ + return d->points; +} + +QPoint Frame::point(int index) const +{ + return d->points.at(index); +} + +int Frame::pointIndex(const QPoint& point) const +{ + return d->points.indexOf(point); +} + +void Frame::addPoint(const QPoint& point, int index) +{ + if(index > -1 && d->points.count() < index) { + d->points.insert(index, point); + } + else { + d->points.append(point); + } +} + +void Frame::removePoint(const QPoint& point) +{ + d->points.removeAll(point); +} + +bool Frame::swapPoints(const QPoint& swapThis, const QPoint& withThis) +{ + int index1 = d->points.indexOf(swapThis); + int index2 = d->points.indexOf(withThis); + if(index1 > -1 && index2 > -1) { + d->points.swap(index1, index2); + return true; + } + return false; +} + +QString Frame::bgcolor() const +{ + return d->bgcolor; +} + +void Frame::setBgcolor(const QString& newColor) +{ + d->bgcolor = newColor; +} diff --git a/src/acbf/AcbfJump.h b/src/acbf/AcbfJump.h new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfJump.h @@ -0,0 +1,118 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 . + * + */ + +#ifndef ACBFJUMP_H +#define ACBFJUMP_H + +#include +#include + +#include "AcbfPage.h" + +#include +/** + * \brief a Class to handle ACBF jumps. + * + * Jumps are areas that point at a specific page. + * + * This allows for a table of contents page that + * can switch to a specific story by the user selecting + * a jump area drawn around the icon for the specific + * story and pointing at the beginning of the story. + * + * Other uses included choose your own adventure style books. + */ +namespace AdvancedComicBookFormat +{ +class ACBF_EXPORT Jump : public QObject +{ + Q_OBJECT + +public: + explicit Jump(Page* parent = nullptr); + ~Jump() override; + + /** + * \brief Write the textarea into the xml writer. + */ + void toXml(QXmlStreamWriter* writer); + /** + * \brief load a textarea element into this object. + * @return True if the xmlReader encountered no errors. + */ + bool fromXml(QXmlStreamReader *xmlReader); + + /** + * @return a list of points that encompasses the textarea. + */ + QList points() const; + /** + * @param index - the index of the desired point. + * @return a point for an index. + */ + QPoint point(int index) const; + /** + * @param point - a point from the points list. + * @return the index of the given point. + */ + int pointIndex(const QPoint& point) const; + + /** + * \brief add a point to the points list. + * @param point - the point to add. Coordinates should be in pixels. + * @param index - the index to add it at. If afterIndex is larger than zero, + * the insertion will happen at that index + */ + void addPoint(const QPoint& point, int index = -1); + /** + * \brief remove a point from the list. + * @param point - point to remove from the list. + */ + void removePoint(const QPoint& point); + /** + * \brief Swap two points in the list. + * @param swapThis - the first points to swap. + * @param withThis - the second points to swap. + */ + bool swapPoints(const QPoint& swapThis, const QPoint& withThis); + + /** + * @brief The page to jump to. + * + * @return int that points at the index of the page to jump to. + */ + int pageIndex() const; + + /** + * @brief set the page to jump to. + * + * @param pageNumber An integer for the index of the page in the + * page list. + */ + void setPageIndex(const int& pageNumber = 0); + +private: + class Private; + std::unique_ptr d; +}; +} + +#endif // ACBFJUMP_H diff --git a/src/acbf/AcbfJump.cpp b/src/acbf/AcbfJump.cpp new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfJump.cpp @@ -0,0 +1,134 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 "AcbfJump.h" +#include +#include + +using namespace AdvancedComicBookFormat; + +class Jump::Private +{ +public: + Private() + : pageIndex(0) + {} + QList points; + int pageIndex; +}; + +Jump::Jump(Page* parent) + : QObject(parent) + , d(new Private) +{ +} + +Jump::~Jump() = default; + +void Jump::toXml(QXmlStreamWriter* writer) { + writer->writeStartElement(QStringLiteral("jump")); + + QStringList points; + Q_FOREACH(const QPoint& point, d->points) { + points << QStringLiteral("%1,%2").arg(QString::number(point.x())).arg(QString::number(point.y())); + } + writer->writeAttribute(QStringLiteral("points"), points.join(' ')); + writer->writeAttribute(QStringLiteral("page"), QString::number(d->pageIndex)); + + writer->writeEndElement(); +} + +bool Jump::fromXml(QXmlStreamReader *xmlReader) +{ + setPageIndex(xmlReader->attributes().value(QStringLiteral("page")).toInt()); + + QStringList points = xmlReader->attributes().value(QStringLiteral("points")).toString().split(' '); + Q_FOREACH(const QString& point, points) { + QStringList elements = point.split(','); + if(elements.length() == 2) + { + addPoint(QPoint(elements.at(0).toInt(), elements.at(1).toInt())); + } + else + { + qWarning() << "Failed to construct one of the points for a frame. Attempted to handle the point" << point << "in the data" << points; + return false; + } + } + + 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 a jump with " << points.count() << "points, to page "<pageIndex; + + return !xmlReader->hasError(); +} + +QList Jump::points() const +{ + return d->points; +} + +QPoint Jump::point(int index) const +{ + return d->points.at(index); +} + +int Jump::pointIndex(const QPoint& point) const +{ + return d->points.indexOf(point); +} + +void Jump::addPoint(const QPoint& point, int index) +{ + if(index > -1 && d->points.count() < index) { + d->points.insert(index, point); + } + else { + d->points.append(point); + } +} + +void Jump::removePoint(const QPoint& point) +{ + d->points.removeAll(point); +} + +bool Jump::swapPoints(const QPoint& swapThis, const QPoint& withThis) +{ + int index1 = d->points.indexOf(swapThis); + int index2 = d->points.indexOf(withThis); + if(index1 > -1 && index2 > -1) { + d->points.swap(index1, index2); + return true; + } + return false; +} + +int Jump::pageIndex() const +{ + return d->pageIndex; +} + +void Jump::setPageIndex(const int& pageNumber) +{ + d->pageIndex = pageNumber; +} diff --git a/src/acbf/AcbfPage.cpp b/src/acbf/AcbfPage.cpp --- a/src/acbf/AcbfPage.cpp +++ b/src/acbf/AcbfPage.cpp @@ -21,6 +21,8 @@ #include "AcbfPage.h" #include "AcbfTextlayer.h" +#include "AcbfFrame.h" +#include "AcbfJump.h" #include #include @@ -85,13 +87,13 @@ layer->toXml(writer); } -// Q_FOREACH(Frame* frame, d->frames) { -// frame->toXml(writer); -// } + Q_FOREACH(Frame* frame, d->frames) { + frame->toXml(writer); + } -// Q_FOREACH(Jump* jump, d->jumps) { -// jump->toXml(writer); -// } + Q_FOREACH(Jump* jump, d->jumps) { + jump->toXml(writer); + } writer->writeEndElement(); } @@ -125,22 +127,28 @@ } d->textLayers[newLayer->language()] = newLayer; } -// else if(xmlReader->name() == "frame") -// { -// Frame* newFrame = new Frame(this); -// if(!newFrame->fromXml()) { -// return false; -// } -// d->frames.append(newFrame); -// } -// else if(xmlReader->name() == "jump") -// { -// Jump* newJump = new Jump(this); -// if(!newJump->fromXml()) { -// return false; -// } -// d->jumps.append(newJump); -// } + else if(xmlReader->name() == QStringLiteral("frame")) + { + Frame* newFrame = new Frame(this); + if(!newFrame->fromXml(xmlReader)) { + return false; + } + d->frames.append(newFrame); + + // Frames have no child elements, so we need to force the reader to go to the next one. + xmlReader->readNext(); + } + else if(xmlReader->name() == QStringLiteral("jump")) + { + Jump* newJump = new Jump(this); + if(!newJump->fromXml(xmlReader)) { + return false; + } + + // Jumps have no child elements, so we need to force the reader to go to the next one. + d->jumps.append(newJump); + xmlReader->readNext(); + } else { qWarning() << Q_FUNC_INFO << "currently unsupported subsection:" << xmlReader->name(); diff --git a/src/acbf/AcbfReference.h b/src/acbf/AcbfReference.h new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfReference.h @@ -0,0 +1,105 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 . + * + */ + +#ifndef ACBFREFERENCE_H +#define ACBFREFERENCE_H + +#include +#include + +#include "acbf_export.h" +class QXmlStreamWriter; +class QXmlStreamReader; + + +namespace AdvancedComicBookFormat +{ +/** + * \brief a Class to handle a single ACBF reference. + * + */ +class References; +class ACBF_EXPORT Reference : public QObject +{ + Q_OBJECT + +public: + explicit Reference(References* parent = nullptr); + ~Reference() override; + + /** + * \brief Write the textarea into the xml writer. + */ + void toXml(QXmlStreamWriter* writer); + /** + * \brief load a textarea element into this object. + * @return True if the xmlReader encountered no errors. + */ + bool fromXml(QXmlStreamReader *xmlReader); + + /** + * @return The ID of this reference data element as a QString. + * Used to identify it from other parts of the + * ACBF document. + */ + QString id() const; + + /** + * \brief Set the ID for this reference element. + * This is used to reference this element from + * other parts of the ACBF document. + * @param newId - The new ID as a string. + */ + void setId(const QString& newId); + + /** + * @returns the language for this reference. + */ + QString language() const; + /** + * \brief set the language for this reference. + * @param language - the language of the entry in language code, country + * code format joined by a dash (not an underscore). + */ + void setLanguage(const QString& language); + + /** + * @returns a list of paragraphs. + * + * Contains allowed sub-elements: strong, emphasis, strikethrough + * sub, sup, a (with mandatory href attribute only) + * Can also contain deprecated sub-elements (superceded by...): code (type option code), + * inverted (textarea option inverted) + */ + QStringList paragraphs() const; + /** + * \brief set the list of paragraphs for this reference. + * @param paragraphs - a list of paragraphs. Can contain sub-elements: + * strong, emphasis, strikethrough, sub, sup, a (with mandatory href attribute only) + */ + void setParagraphs(const QStringList& paragraphs); +private: + class Private; + std::unique_ptr d; +}; +} + +#endif // ACBFREFERENCE_H diff --git a/src/acbf/AcbfReference.cpp b/src/acbf/AcbfReference.cpp new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfReference.cpp @@ -0,0 +1,116 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 "AcbfReference.h" +#include "AcbfReferences.h" +#include +#include +#include +#include + +using namespace AdvancedComicBookFormat; + +class Reference::Private { +public: + Private() {} + QString id; + QString language; + QStringList paragraphs; +}; + +Reference::Reference(References* parent) + : QObject(parent) + , d(new Private) +{ + qRegisterMetaType("Reference*"); +} + +Reference::~Reference() = default; + +void Reference::toXml(QXmlStreamWriter* writer) +{ + writer->writeStartElement(QStringLiteral("reference")); + writer->writeAttribute(QStringLiteral("id"), id()); + /* ACBF 1.2 + writer->writeAttribute(QStringLiteral("lang"), language()); + */ + Q_FOREACH(const QString& paragraph, d->paragraphs) { + writer->writeStartElement(QStringLiteral("p")); + writer->writeCharacters(paragraph); + writer->writeEndElement(); + } + writer->writeEndElement(); +} + +bool Reference::fromXml(QXmlStreamReader *xmlReader) +{ + qDebug()<< "Getting the reference"; + setId(xmlReader->attributes().value(QStringLiteral("id")).toString()); + setLanguage(xmlReader->attributes().value(QStringLiteral("lang")).toString()); + while(xmlReader->readNextStartElement()) + { + if(xmlReader->name() == QStringLiteral("p")) + { + qDebug()<<"Getting the paragraphs"; + d->paragraphs.append(xmlReader->readElementText(QXmlStreamReader::IncludeChildElements)); + } + else + { + qWarning() << Q_FUNC_INFO << "currently unsupported subsection in text-area:" << 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 a reference of with id" << id(); + return !xmlReader->hasError(); +} + +QString Reference::id() const +{ + return d->id; +} + +void Reference::setId(const QString& newId) +{ + d->id = newId; +} + +QString Reference::language() const +{ + return d->language; +} + +void Reference::setLanguage(const QString& language) +{ + d->language = language; +} + +QStringList Reference::paragraphs() const +{ + return d->paragraphs; +} + +void Reference::setParagraphs(const QStringList& paragraphs) +{ + d->paragraphs = paragraphs; +} diff --git a/src/acbf/AcbfReferences.h b/src/acbf/AcbfReferences.h new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfReferences.h @@ -0,0 +1,75 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 . + * + */ + +#ifndef ACBFREFERENCES_H +#define ACBFREFERENCES_H + +#include + +#include "AcbfDocument.h" +#include "AcbfReference.h" +#include +#include + + +namespace AdvancedComicBookFormat +{ + +class ACBF_EXPORT References : public QObject +{ + Q_OBJECT + +public: + explicit References(Document* parent = nullptr); + ~References() override; + + /** + * \brief Write the textarea into the xml writer. + */ + void toXml(QXmlStreamWriter* writer); + /** + * \brief load a textarea element into this object. + * @return True if the xmlReader encountered no errors. + */ + bool fromXml(QXmlStreamReader *xmlReader); + + /** + * @param id - the id that is used to reference to this object. + * @return the reference object referenced by this id. + */ + Reference* reference(const QString& id) const; + + /** + * @brief Add reference at ID. + * + * @param id The id that will refer to this reference. + * @param paragraphs The paragraphs comprising this reference. + * @param language The language (optional, and 1.2 only) + */ + void setReference(const QString& id, const QStringList& paragraphs, const QString& language = ""); + +private: + class Private; + std::unique_ptr d; +}; +} + +#endif // ACBFREFERENCES_H diff --git a/src/acbf/AcbfReferences.cpp b/src/acbf/AcbfReferences.cpp new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfReferences.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 "AcbfReferences.h" +#include +#include + +using namespace AdvancedComicBookFormat; + +class References::Private { +public: + Private() {} + QHash references; +}; + +References::References(Document* parent) + : QObject(parent) + , d(new Private) +{ + qRegisterMetaType("References*"); +} + +References::~References() = default; + +void References::toXml(QXmlStreamWriter* writer) { + writer->writeStartElement(QStringLiteral("references")); + + Q_FOREACH(Reference* reference, d->references) { + reference->toXml(writer); + } + writer->writeEndElement(); +} + +bool References::fromXml(QXmlStreamReader *xmlReader) +{ + + while(xmlReader->readNextStartElement()) + { + if(xmlReader->name() == QStringLiteral("reference")) + { + Reference* newReference = new Reference(this); + if(!newReference->fromXml(xmlReader)) { + return false; + } + d->references.insert(newReference->id(), newReference); + } + 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 reference section with" << d->references.count() << "references"; + + return !xmlReader->hasError(); +} + +Reference* References::reference(const QString& id) const +{ + return d->references.value(id); +} + +void References::setReference(const QString& id, const QStringList& paragraphs, const QString& language) { + Reference* ref = new Reference(this); + ref->setId(id); + ref->setParagraphs(paragraphs); + ref->setLanguage(language); + d->references.insert(ref->id(), ref); +} diff --git a/src/acbf/AcbfStyleSheet.h b/src/acbf/AcbfStyleSheet.h new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfStyleSheet.h @@ -0,0 +1,75 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 . + * + */ + +#ifndef ACBFSTYLESHEET_H +#define ACBFSTYLESHEET_H + +#include +#include +#include + +#include "AcbfDocument.h" +class QXmlStreamWriter; +class QXmlStreamReader; + + +namespace AdvancedComicBookFormat +{ + +class ACBF_EXPORT StyleSheet : public QObject +{ + Q_OBJECT + +public: + explicit StyleSheet(Document* parent = nullptr); + ~StyleSheet() override; + + /** + * \brief Write the textarea into the xml writer. + */ + void toXml(QXmlStreamWriter* writer); + /** + * \brief load a textarea element into this object. + * @return True if the xmlReader encountered no errors. + */ + bool fromXml(QXmlStreamReader *xmlReader); + + /** + * @brief the contents of the style section. + * + * @return A QHash with Css selectors and their contents; + */ + QHash classes() const; + + /** + * @brief set the contents of the style section + * + * @param css a QString containing a css stylesheet. + */ + void setContents(const QString& css = QString()); + +private: + class Private; + std::unique_ptr d; +}; +} + +#endif // ACBFSTYLESHEET_H diff --git a/src/acbf/AcbfStyleSheet.cpp b/src/acbf/AcbfStyleSheet.cpp new file mode 100644 --- /dev/null +++ b/src/acbf/AcbfStyleSheet.cpp @@ -0,0 +1,81 @@ +/* + * Copyright 2018 Wolthera van Hövell tot Westerflier + * + * 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 "AcbfStyleSheet.h" +#include +#include +#include +#include + +using namespace AdvancedComicBookFormat; + +class StyleSheet::Private +{ +public: + Private(){} + QHash classes; +}; + +StyleSheet::StyleSheet(Document* parent) + : QObject(parent) + , d(new Private) +{ +} + +StyleSheet::~StyleSheet() = default; + +void StyleSheet::toXml(QXmlStreamWriter* writer) { + writer->writeStartElement(QStringLiteral("style")); + QStringList contents; + Q_FOREACH(const QString selector, d->classes.keys()) + { + contents.append(selector+" {\n"+d->classes[selector]+"\n}"); + } + writer->writeCharacters(contents.join("\n")); + writer->writeEndElement(); +} + +bool StyleSheet::fromXml(QXmlStreamReader *xmlReader) +{ + setContents(xmlReader->readElementText(QXmlStreamReader::IncludeChildElements)); + 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 a stylesheet section with"<classes.keys().count()<<"classes"; + return !xmlReader->hasError(); +} + +QHash StyleSheet::classes() const +{ + return d->classes; +} +void StyleSheet::setContents(const QString& css) +{ + QStringList classes = css.split('}', QString::SkipEmptyParts); + Q_FOREACH(const QString &cssClass, classes) + { + QStringList selectorContent = cssClass.split('{', QString::SkipEmptyParts); + if (selectorContent.count() == 2) { + d->classes.insert(selectorContent[0], selectorContent[1]); + } + } + +} diff --git a/src/acbf/AcbfTextarea.cpp b/src/acbf/AcbfTextarea.cpp --- a/src/acbf/AcbfTextarea.cpp +++ b/src/acbf/AcbfTextarea.cpp @@ -210,6 +210,7 @@ QStringLiteral("audio"), // (speech emanating from an audio device, e.g., television or radio speaker, telephone, walkie-talkie, etc.) QStringLiteral("thought"), QStringLiteral("sign"), // (any kind of sign/writing, text is centered) + QStringLiteral("sound"), // /new in 1.2/ }; } diff --git a/src/acbf/CMakeLists.txt b/src/acbf/CMakeLists.txt --- a/src/acbf/CMakeLists.txt +++ b/src/acbf/CMakeLists.txt @@ -17,6 +17,11 @@ AcbfSequence.cpp AcbfTextarea.cpp AcbfTextlayer.cpp + AcbfFrame.cpp + AcbfJump.cpp + AcbfReferences.cpp + AcbfReference.cpp + AcbfStyleSheet.cpp ) add_library(acbf SHARED ${acbf_SRCS}) diff --git a/src/creator/qml/BookMetainfoPage.qml b/src/creator/qml/BookMetainfoPage.qml --- a/src/creator/qml/BookMetainfoPage.qml +++ b/src/creator/qml/BookMetainfoPage.qml @@ -143,7 +143,7 @@ onClicked: { if(parent.text !== "") { // Just add an author where only the nickname is defined - root.model.acbfData.metaData.bookInfo.addAuthor("", "", "", "", "", parent.text, "", ""); + root.model.acbfData.metaData.bookInfo.addAuthor("", "", "", "", "", parent.text, [""], [""]); root.model.setDirty(); parent.text = ""; } @@ -283,7 +283,7 @@ id: authorEditor; bookinfo: root.model.acbfData.metaData.bookInfo; onSave: { - root.model.acbfData.metaData.bookInfo.setAuthor(index, activity, language, firstName, middleName, lastName, nickName, homePage, email); + root.model.acbfData.metaData.bookInfo.setAuthor(index, activity, language, firstName, middleName, lastName, nickName, [homePage], [email]); root.model.setDirty(); } } diff --git a/src/creator/qml/metainfoeditors/AuthorEntryEditor.qml b/src/creator/qml/metainfoeditors/AuthorEntryEditor.qml --- a/src/creator/qml/metainfoeditors/AuthorEntryEditor.qml +++ b/src/creator/qml/metainfoeditors/AuthorEntryEditor.qml @@ -39,8 +39,12 @@ middleNameField.text = root.author.middleName(); lastNameField.text = root.author.lastName(); nickNameField.text = root.author.nickName(); - homePageField.text = root.author.homePage(); - emailField.text = root.author.email(); + if (root.author.homePages.count > 0) { + homePageField.text = root.author.homePages()[0]; + } + if (root.author.emails.count > 0) { + emailField.text = root.author.emails()[0]; + } } property QtObject author: null;