.
[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             foreach (TreeItem *child, children) {
33                 child->addToBook(book);
34             }
35         }
36         QList<TreeItem *> children;
37         QString id;
38         QString href;
39         QString name;
40         TreeItem *parent;
41         int depth;
42     };
43
44     NcxHandler(Book &b): book(b), rootItem(0), currentItem(0) {
45         book.chapters.clear();
46     }
47
48     ~NcxHandler() {
49         delete rootItem;
50     }
51
52     bool endElement(const QString &namespaceUri, const QString &name,
53                     const QString &qName) {
54         (void)namespaceUri;
55         (void)qName;
56         if (name == "text") {
57             if (currentItem) {
58                 if (currentItem) {
59                     currentItem->name = currentText;
60                 }
61             }
62         } else if (name == "navPoint") {
63             if (currentItem) {
64                 currentItem = currentItem->parent;
65                 if (currentItem == 0) {
66                     // Root navigation point reached, dump TOC tree
67                     rootItem->addToBook(book);
68                     delete rootItem;
69                     rootItem = 0;
70                 }
71             }
72         }
73         return true;
74     }
75
76     bool startElement(const QString &namespaceUri, const QString &name,
77                       const QString &qName, const QXmlAttributes &attrs) {
78         (void)namespaceUri;
79         (void)qName;
80         currentText = "";
81         if (name == "navPoint") {
82             TreeItem *item = new TreeItem(attrs.value("id"), currentItem);
83             if (!rootItem) {
84                 rootItem = item;
85             }
86             currentItem = item;
87         } else if (name == "content") {
88             if (currentItem) {
89                 currentItem->href = attrs.value("src");
90             }
91         }
92         return true;
93     }
94
95 private:
96     Book &book;
97     QString contentId;
98     QString contentUrl;
99     QString contentTitle;
100     TreeItem *rootItem;
101     TreeItem *currentItem;
102 };
103
104 #endif // NCXHANDLER_H