1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Assistant of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 #include "tracer.h"
29
30 #include "xbelsupport.h"
31
32 #include "bookmarkitem.h"
33 #include "bookmarkmodel.h"
34
35 #include <QtCore/QDate>
36 #include <QtCore/QModelIndex>
37
38 QT_BEGIN_NAMESPACE
39
40 struct Bookmark {
41 QString title;
42 QString url;
43 bool folded;
44 };
45
XbelWriter(BookmarkModel * model)46 XbelWriter::XbelWriter(BookmarkModel *model)
47 : QXmlStreamWriter()
48 , bookmarkModel(model)
49 {
50 TRACE_OBJ
51 setAutoFormatting(true);
52 }
53
writeToFile(QIODevice * device)54 void XbelWriter::writeToFile(QIODevice *device)
55 {
56 TRACE_OBJ
57 setDevice(device);
58
59 writeStartDocument();
60 writeDTD(QLatin1String("<!DOCTYPE xbel>"));
61 writeStartElement(QLatin1String("xbel"));
62 writeAttribute(QLatin1String("version"), QLatin1String("1.0"));
63
64 const QModelIndex root;
65 for (int i = 0; i < bookmarkModel->rowCount(root); ++i)
66 writeData(bookmarkModel->index(i, 0, root));
67 writeEndDocument();
68 }
69
writeData(const QModelIndex & index)70 void XbelWriter::writeData(const QModelIndex &index)
71 {
72 TRACE_OBJ
73 if (index.isValid()) {
74 Bookmark entry;
75 entry.title = index.data().toString();
76 entry.url = index.data(UserRoleUrl).toString();
77
78 if (index.data(UserRoleFolder).toBool()) {
79 writeStartElement(QLatin1String("folder"));
80 entry.folded = !index.data(UserRoleExpanded).toBool();
81 writeAttribute(QLatin1String("folded"), entry.folded
82 ? QLatin1String("yes") : QLatin1String("no"));
83 writeTextElement(QLatin1String("title"), entry.title);
84
85 for (int i = 0; i < bookmarkModel->rowCount(index); ++i)
86 writeData(bookmarkModel->index(i, 0 , index));
87 writeEndElement();
88 } else {
89 writeStartElement(QLatin1String("bookmark"));
90 writeAttribute(QLatin1String("href"), entry.url);
91 writeTextElement(QLatin1String("title"), entry.title);
92 writeEndElement();
93 }
94 }
95 }
96
97 // -- XbelReader
98
XbelReader(BookmarkModel * model)99 XbelReader::XbelReader(BookmarkModel *model)
100 : QXmlStreamReader()
101 , bookmarkModel(model)
102 {
103 TRACE_OBJ
104 }
105
readFromFile(QIODevice * device)106 bool XbelReader::readFromFile(QIODevice *device)
107 {
108 TRACE_OBJ
109 setDevice(device);
110
111 while (!atEnd()) {
112 readNext();
113
114 if (isStartElement()) {
115 if (name() == QLatin1String("xbel")
116 && attributes().value(QLatin1String("version"))
117 == QLatin1String("1.0")) {
118 const QModelIndex root;
119 parents.append(bookmarkModel->addItem(root, true));
120 readXBEL();
121 bookmarkModel->setData(parents.first(),
122 QDate::currentDate().toString(Qt::ISODate), Qt::EditRole);
123 } else {
124 raiseError(QLatin1String("The file is not an XBEL version 1.0 file."));
125 }
126 }
127 }
128
129 return !error();
130 }
131
readXBEL()132 void XbelReader::readXBEL()
133 {
134 TRACE_OBJ
135 while (!atEnd()) {
136 readNext();
137
138 if (isEndElement())
139 break;
140
141 if (isStartElement()) {
142 if (name() == QLatin1String("folder"))
143 readFolder();
144 else if (name() == QLatin1String("bookmark"))
145 readBookmark();
146 else
147 readUnknownElement();
148 }
149 }
150 }
151
readFolder()152 void XbelReader::readFolder()
153 {
154 TRACE_OBJ
155 parents.append(bookmarkModel->addItem(parents.last(), true));
156 bookmarkModel->setData(parents.last(),
157 attributes().value(QLatin1String("folded")) == QLatin1String("no"),
158 UserRoleExpanded);
159
160 while (!atEnd()) {
161 readNext();
162
163 if (isEndElement())
164 break;
165
166 if (isStartElement()) {
167 if (name() == QLatin1String("title")) {
168 bookmarkModel->setData(parents.last(), readElementText(),
169 Qt::EditRole);
170 } else if (name() == QLatin1String("folder"))
171 readFolder();
172 else if (name() == QLatin1String("bookmark"))
173 readBookmark();
174 else
175 readUnknownElement();
176 }
177 }
178
179 parents.removeLast();
180 }
181
readBookmark()182 void XbelReader::readBookmark()
183 {
184 TRACE_OBJ
185 const QModelIndex &index = bookmarkModel->addItem(parents.last(), false);
186 if (BookmarkItem* item = bookmarkModel->itemFromIndex(index)) {
187 item->setData(UserRoleUrl, attributes().value(QLatin1String("href"))
188 .toString());
189 }
190
191 while (!atEnd()) {
192 readNext();
193
194 if (isEndElement())
195 break;
196
197 if (isStartElement()) {
198 if (name() == QLatin1String("title"))
199 bookmarkModel->setData(index, readElementText(), Qt::EditRole);
200 else
201 readUnknownElement();
202 }
203 }
204 }
205
readUnknownElement()206 void XbelReader::readUnknownElement()
207 {
208 TRACE_OBJ
209 while (!atEnd()) {
210 readNext();
211
212 if (isEndElement())
213 break;
214
215 if (isStartElement())
216 readUnknownElement();
217 }
218 }
219
220 QT_END_NAMESPACE
221