-To dos migrated to Maemo Garage:
-https://garage.maemo.org/tracker/?group_id=1757 . Old to dos below are kept as
-historical artifacts.
+To do list migrated to Maemo Garage:
+https://garage.maemo.org/tracker/?group_id=1757 . Old to do list below is kept as
+historical artifact.
To Do
-----
#include "book.h"
#include "opshandler.h"
-#include "opserrorhandler.h"
+#include "xmlerrorhandler.h"
#include "extractzip.h"
#include "library.h"
#include "containerhandler.h"
+#include "ncxhandler.h"
Book::Book()
{
"</title></head><body><h1>" + Qt::escape(error) + "</h1><p>" +
Qt::escape(details) + "</p></body></html>";
content["error"].href = errorPage;
- content["error"].type = "text/html";
+ content["error"].name = "Error";
}
bool Book::extract()
qDebug() << "Book::parse";
bool ret = false;
- QFile bookFile(opsPath());
+ QString opsFileName = opsPath();
+ qDebug() << " Parsing OPS file" << opsFileName;
+ QFile opsFile(opsFileName);
QXmlSimpleReader reader;
- QXmlInputSource *source = new QXmlInputSource(&bookFile);
+ QXmlInputSource *source = new QXmlInputSource(&opsFile);
OpsHandler *opsHandler = new OpsHandler(*this);
- OpsErrorHandler *opsErrorHandler = new OpsErrorHandler();
+ XmlErrorHandler *errorHandler = new XmlErrorHandler();
reader.setContentHandler(opsHandler);
- reader.setErrorHandler(opsErrorHandler);
-
+ reader.setErrorHandler(errorHandler);
ret = reader.parse(source);
- if (!ret) {
- qCritical() << "*** Book::parse: XML parsing failed";
- }
-
+ delete errorHandler;
delete opsHandler;
delete source;
+
+ // If there is an "ncx" item in content, parse it: That's the real table of
+ // contents
+ if (content.contains("ncx")) {
+ QString ncxFileName = content["ncx"].href;
+ qDebug() << " Parsing NCX file" << ncxFileName;
+ QFile ncxFile(ncxFileName);
+ source = new QXmlInputSource(&ncxFile);
+ NcxHandler *ncxHandler = new NcxHandler(*this);
+ errorHandler = new XmlErrorHandler();
+ reader.setContentHandler(ncxHandler);
+ reader.setErrorHandler(errorHandler);
+ ret = reader.parse(source);
+ delete ncxHandler;
+ delete errorHandler;
+ delete source;
+ }
+
return ret;
}
QXmlSimpleReader reader;
QXmlInputSource *source = new QXmlInputSource(&container);
ContainerHandler *containerHandler = new ContainerHandler();
- OpsErrorHandler *opsErrorHandler = new OpsErrorHandler();
+ XmlErrorHandler *errorHandler = new XmlErrorHandler();
reader.setContentHandler(containerHandler);
- reader.setErrorHandler(opsErrorHandler);
+ reader.setErrorHandler(errorHandler);
if (reader.parse(source)) {
ret = tmpDir() + "/" + containerHandler->rootFile;
mRootPath = QFileInfo(ret).absoluteDir().absolutePath();
qDebug() << " OSP path" << ret;
qDebug() << " Root dir" << mRootPath;
}
+ delete errorHandler;
delete containerHandler;
delete source;
return ret;
struct ContentItem
{
QString href;
- QString type;
+ QString name;
};
/** Bookmark: a volume index and a relative position in volume. */
QString subject; //< Subject.
QString source; //< Source.
QString rights; //< Rights.
+ QString tocPath; //< Path to toc ncx.
+ QString coverPath; //< Path to cover html.
+ QString coverImagePath; //< Path to cover image.
protected:
/** Indicate failure by creating a single "error" content item. */
list = new QListWidget(this);
list->setSelectionMode(QAbstractItemView::SingleSelection);
foreach (Book::Bookmark bookmark, book_->bookmarks()) {
- list->addItem("Volume " + QString::number(bookmark.chapter + 1) + ", at " +
+ QString contentId = book_->toc[bookmark.chapter];
+ QString contentTitle = book_->content[contentId].name;
+ list->addItem(contentTitle + ", at " +
QString::number((int)(bookmark.pos * 100)) + "%");
}
}
else if (key == "font") {
QString face = Settings::instance()->value("font").toString();
- qDebug() << "" << face;
settings()->setFontFamily(QWebSettings::StandardFont, face);
}
else if (key == "scheme") {
QWebFrame *frame = page()->mainFrame();
QString scheme = Settings::instance()->value("scheme").toString();
- qDebug() << "" << scheme;
if ((scheme != "day") && (scheme != "night") && (scheme != "sand") &&
(scheme != "default")) {
scheme = "default";
QString scriptText = script.readAll();
script.close();
QVariant ret = frame->evaluateJavaScript(scriptText);
- qDebug() << "" << script.fileName() << ":" << scriptText;
- qDebug() << "" << ret;
}
}
settingswindow.h \
settings.h \
bookmarksdialog.h \
- opserrorhandler.h \
+ xmlerrorhandler.h \
containerhandler.h \
- sortedlibrary.h
+ sortedlibrary.h \
+ ncxhandler.h
RESOURCES += \
dorian.qrc
--- /dev/null
+#ifndef NCXHANDLER_H
+#define NCXHANDLER_H
+
+#include <QXmlContentHandler>
+
+#include "book.h"
+
+/** XML content handler for NCX format. */
+class NcxHandler: public QXmlContentHandler
+{
+public:
+ bool endDocument() {return true;}
+ bool endPrefixMapping(const QString &) {return true;}
+ QString errorString() const {return "";}
+ bool ignorableWhitespace(const QString &) {return true;}
+ bool processingInstruction(const QString &, const QString &) {return true;}
+ void setDocumentLocator(QXmlLocator *) {}
+ bool skippedEntity(const QString &) {return true;}
+ bool startDocument() {return true;}
+ bool startPrefixMapping(const QString &, const QString &) {return true;}
+
+ NcxHandler(Book &b): book(b)
+ {
+ book.toc.clear();
+ }
+
+ bool characters(const QString &ch)
+ {
+ currentText += ch;
+ return true;
+ }
+
+ bool endElement(const QString &namespaceUri, const QString &name,
+ const QString &qName)
+ {
+ (void)namespaceUri;
+ (void)qName;
+ if (name == "text") {
+ contentTitle = currentText;
+ } else if (name == "navPoint") {
+ Book::ContentItem item;
+ item.href = book.rootPath() + "/" + contentUrl;
+ item.name = contentTitle;
+ book.content[contentId] = item;
+ book.toc.append(contentId);
+ }
+ return true;
+ }
+
+ bool startElement(const QString &namespaceUri, const QString &name,
+ const QString &qName, const QXmlAttributes &attrs)
+ {
+ (void)namespaceUri;
+ (void)qName;
+ currentText = "";
+ if (name == "navPoint") {
+ contentId = attrs.value("id");
+ } else if (name == "content") {
+ contentUrl = attrs.value("src");
+ }
+ return true;
+ }
+
+private:
+ Book &book;
+ QString currentText;
+ QString contentId;
+ QString contentUrl;
+ QString contentTitle;
+};
+
+#endif // NCXHANDLER_H
+++ /dev/null
-#ifndef OPSERRORHANDLER_H
-#define OPSERRORHANDLER_H
-
-#include <QXmlErrorHandler>
-#include <QDebug>
-
-#include "book.h"
-
-/**
- XML error handler for OPS format.
- */
-class OpsErrorHandler: public QXmlErrorHandler
-{
- bool error(const QXmlParseException &e) {
- qDebug() << "OpsErrorHandler::error" << e.message() << "at line"
- << e.lineNumber();
- return true;
- }
- virtual QString errorString() const {return QString();}
- virtual bool fatalError(const QXmlParseException &e) {
- qDebug() << "OpsErrorHandler::fatalError" << e.message() << "at line"
- << e.lineNumber();
- return true;
- }
- virtual bool warning(const QXmlParseException &e) {
- qDebug() << "OpsErrorHandler::warning" << e.message() << "at line"
- << e.lineNumber();
- return true;
- }
-};
-
-#endif // OPSERRORHANDLER_H
class OpsHandler: public QXmlContentHandler
{
public:
- OpsHandler(Book &book): mBook(book) {}
+ OpsHandler(Book &b): book(b), partCount(0) {}
bool endDocument() {return true;}
bool endPrefixMapping(const QString &) {return true;}
QString errorString() const {return "";}
bool characters(const QString &ch)
{
- mCurrentText += ch;
+ currentText += ch;
return true;
}
{
(void)namespaceUri;
(void)qName;
- if (mCurrentText != "") {
+ if (currentText != "") {
if (name == "title") {
- mBook.title = mCurrentText;
+ book.title = currentText;
}
else if (name == "creator") {
- mBook.creators.append(mCurrentText);
+ book.creators.append(currentText);
}
else if (name == "publisher") {
- mBook.publisher = mCurrentText;
+ book.publisher = currentText;
}
else if (name == "subject") {
- mBook.subject = mCurrentText;
+ book.subject = currentText;
}
else if (name == "source") {
- mBook.source = mCurrentText;
+ book.source = currentText;
}
else if (name == "rights") {
- mBook.rights = mCurrentText;
+ book.rights = currentText;
}
}
return true;
const QString &qName, const QXmlAttributes &attrs)
{
(void)namespaceUri;
- (void)name;
(void)qName;
- (void)attrs;
- mCurrentText = "";
+ currentText = "";
if (name == "item") {
Book::ContentItem item;
- item.href = mBook.rootPath() + "/" + attrs.value("href");
- item.type = attrs.value("media-type");
+ item.href = book.rootPath() + "/" + attrs.value("href");
+ item.name = QString("Part %1").arg(partCount + 1);
QString key = attrs.value("id");
- mBook.content[key] = item;
- qDebug() << "OpsHandler::startElement: item" << key << "type"
- << item.type << "href" << item.href;
+ book.content[key] = item;
+ partCount++;
}
else if (name == "itemref") {
- mBook.toc.append(attrs.value("idref"));
- qDebug() << "OpsHandler::startElement: itemref" << attrs.value("idref");
+ book.toc.append(attrs.value("idref"));
}
return true;
}
private:
- Book &mBook;
- QString mCurrentText;
+ Book &book;
+ QString currentText;
+ int partCount;
};
#endif // OPSHANDLER_H
* Show message if selected book is already in the library
* Make library window full screen on Maemo
* Show busy indicator while loading book
- * Create Maemo Garage web pages
+ * Create Maemo Garage web page
+ * Read chapter titles from NCX directory
+ * Display chapter titles for bookmarks
-- Akos Polster <akos@pipacs.com> Fri, 16 Jul 2010 20:00:00 +0200
--- /dev/null
+#ifndef XMLERRORHANDLER_H
+#define XMLERRORHANDLER_H
+
+#include <QXmlErrorHandler>
+#include <QDebug>
+
+/** Generic XML error handler. */
+class XmlErrorHandler: public QXmlErrorHandler
+{
+ bool error(const QXmlParseException &e) {
+ qCritical() << "*** XmlErrorHandler::error" << e.message() << "at line"
+ << e.lineNumber();
+ return true;
+ }
+ QString errorString() const {return QString();}
+ bool fatalError(const QXmlParseException &e) {
+ qCritical() << "*** XmlErrorHandler::fatalError" << e.message()
+ << "at line" << e.lineNumber();
+ return true;
+ }
+ bool warning(const QXmlParseException &e) {
+ qWarning() << "XmlErrorHandler::warning" << e.message() << "at line"
+ << e.lineNumber();
+ return true;
+ }
+};
+
+#endif // XMLERRORHANDLER_H