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