Load books on demand.
[dorian] / model / ncxhandler.h
1 #ifndef NCXHANDLER_H
2 #define NCXHANDLER_H
3
4 #include "xmlhandler.h"
5 #include "book.h"
6 #include "trace.h"
7
8 /** XML content handler for NCX format. */
9 class NcxHandler: public XmlHandler
10 {
11 public:
12     struct TreeItem
13     {
14         TreeItem(const QString &i, TreeItem *p = 0): id(i), parent(p) {
15             if (parent) {
16                 parent->children.append(this);
17                 depth = parent->depth + 1;
18             } else {
19                 depth = 0;
20             }
21         }
22         ~TreeItem() {
23             qDeleteAll(children);
24         }
25         void addToBook(Book &book) {
26             Book::ContentItem contentItem;
27             contentItem.href = href;
28             contentItem.name = QString(" ").repeated(depth) + name;
29             contentItem.size = 0;
30             book.content[id] = contentItem;
31             book.chapters.append(id);
32             qDebug() << "" << id << "name" << name << "href" << href;
33             foreach (TreeItem *child, children) {
34                 child->addToBook(book);
35             }
36         }
37         QList<TreeItem *> children;
38         QString id;
39         QString href;
40         QString name;
41         TreeItem *parent;
42         int depth;
43     };
44
45     NcxHandler(Book &b): book(b), rootItem(0), currentItem(0) {
46         book.chapters.clear();
47     }
48
49     ~NcxHandler() {
50         delete rootItem;
51     }
52
53     bool endElement(const QString &namespaceUri, const QString &name,
54                     const QString &qName) {
55         (void)namespaceUri;
56         (void)qName;
57         if (name == "text") {
58             if (currentItem) {
59                 if (currentItem) {
60                     currentItem->name = currentText;
61                 }
62             }
63         } else if (name == "navPoint") {
64             if (currentItem) {
65                 qDebug() << "NcxHandler::endElement  " << currentItem->id;
66                 currentItem = currentItem->parent;
67                 if (currentItem == 0) {
68                     qDebug() << " Root item reached, dumping tree";
69                     rootItem->addToBook(book);
70                     delete rootItem;
71                     rootItem = 0;
72                 }
73             }
74         }
75         return true;
76     }
77
78     bool startElement(const QString &namespaceUri, const QString &name,
79                       const QString &qName, const QXmlAttributes &attrs) {
80         (void)namespaceUri;
81         (void)qName;
82         currentText = "";
83         if (name == "navPoint") {
84             TreeItem *item = new TreeItem(attrs.value("id"), currentItem);
85             qDebug() << "NcxHandler::startElement" << attrs.value("id");
86             if (!rootItem) {
87                 rootItem = item;
88             }
89             currentItem = item;
90         } else if (name == "content") {
91             if (currentItem) {
92                 currentItem->href = attrs.value("src");
93             }
94         }
95         return true;
96     }
97
98 private:
99     Book &book;
100     QString contentId;
101     QString contentUrl;
102     QString contentTitle;
103     TreeItem *rootItem;
104     TreeItem *currentItem;
105 };
106
107 #endif // NCXHANDLER_H