|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the demonstration applications of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "xbel.h" |
|
43 |
|
44 #include <QtCore/QFile> |
|
45 |
|
46 BookmarkNode::BookmarkNode(BookmarkNode::Type type, BookmarkNode *parent) : |
|
47 expanded(false) |
|
48 , m_parent(parent) |
|
49 , m_type(type) |
|
50 { |
|
51 if (parent) |
|
52 parent->add(this); |
|
53 } |
|
54 |
|
55 BookmarkNode::~BookmarkNode() |
|
56 { |
|
57 if (m_parent) |
|
58 m_parent->remove(this); |
|
59 qDeleteAll(m_children); |
|
60 m_parent = 0; |
|
61 m_type = BookmarkNode::Root; |
|
62 } |
|
63 |
|
64 bool BookmarkNode::operator==(const BookmarkNode &other) |
|
65 { |
|
66 if (url != other.url |
|
67 || title != other.title |
|
68 || desc != other.desc |
|
69 || expanded != other.expanded |
|
70 || m_type != other.m_type |
|
71 || m_children.count() != other.m_children.count()) |
|
72 return false; |
|
73 |
|
74 for (int i = 0; i < m_children.count(); ++i) |
|
75 if (!((*(m_children[i])) == (*(other.m_children[i])))) |
|
76 return false; |
|
77 return true; |
|
78 } |
|
79 |
|
80 BookmarkNode::Type BookmarkNode::type() const |
|
81 { |
|
82 return m_type; |
|
83 } |
|
84 |
|
85 void BookmarkNode::setType(Type type) |
|
86 { |
|
87 m_type = type; |
|
88 } |
|
89 |
|
90 QList<BookmarkNode *> BookmarkNode::children() const |
|
91 { |
|
92 return m_children; |
|
93 } |
|
94 |
|
95 BookmarkNode *BookmarkNode::parent() const |
|
96 { |
|
97 return m_parent; |
|
98 } |
|
99 |
|
100 void BookmarkNode::add(BookmarkNode *child, int offset) |
|
101 { |
|
102 Q_ASSERT(child->m_type != Root); |
|
103 if (child->m_parent) |
|
104 child->m_parent->remove(child); |
|
105 child->m_parent = this; |
|
106 if (-1 == offset) |
|
107 offset = m_children.size(); |
|
108 m_children.insert(offset, child); |
|
109 } |
|
110 |
|
111 void BookmarkNode::remove(BookmarkNode *child) |
|
112 { |
|
113 child->m_parent = 0; |
|
114 m_children.removeAll(child); |
|
115 } |
|
116 |
|
117 |
|
118 XbelReader::XbelReader() |
|
119 { |
|
120 } |
|
121 |
|
122 BookmarkNode *XbelReader::read(const QString &fileName) |
|
123 { |
|
124 QFile file(fileName); |
|
125 if (!file.exists()) { |
|
126 return new BookmarkNode(BookmarkNode::Root); |
|
127 } |
|
128 file.open(QFile::ReadOnly); |
|
129 return read(&file); |
|
130 } |
|
131 |
|
132 BookmarkNode *XbelReader::read(QIODevice *device) |
|
133 { |
|
134 BookmarkNode *root = new BookmarkNode(BookmarkNode::Root); |
|
135 setDevice(device); |
|
136 if (readNextStartElement()) { |
|
137 QString version = attributes().value(QLatin1String("version")).toString(); |
|
138 if (name() == QLatin1String("xbel") |
|
139 && (version.isEmpty() || version == QLatin1String("1.0"))) { |
|
140 readXBEL(root); |
|
141 } else { |
|
142 raiseError(QObject::tr("The file is not an XBEL version 1.0 file.")); |
|
143 } |
|
144 } |
|
145 return root; |
|
146 } |
|
147 |
|
148 void XbelReader::readXBEL(BookmarkNode *parent) |
|
149 { |
|
150 Q_ASSERT(isStartElement() && name() == QLatin1String("xbel")); |
|
151 |
|
152 while (readNextStartElement()) { |
|
153 if (name() == QLatin1String("folder")) |
|
154 readFolder(parent); |
|
155 else if (name() == QLatin1String("bookmark")) |
|
156 readBookmarkNode(parent); |
|
157 else if (name() == QLatin1String("separator")) |
|
158 readSeparator(parent); |
|
159 else |
|
160 skipCurrentElement(); |
|
161 } |
|
162 } |
|
163 |
|
164 void XbelReader::readFolder(BookmarkNode *parent) |
|
165 { |
|
166 Q_ASSERT(isStartElement() && name() == QLatin1String("folder")); |
|
167 |
|
168 BookmarkNode *folder = new BookmarkNode(BookmarkNode::Folder, parent); |
|
169 folder->expanded = (attributes().value(QLatin1String("folded")) == QLatin1String("no")); |
|
170 |
|
171 while (readNextStartElement()) { |
|
172 if (name() == QLatin1String("title")) |
|
173 readTitle(folder); |
|
174 else if (name() == QLatin1String("desc")) |
|
175 readDescription(folder); |
|
176 else if (name() == QLatin1String("folder")) |
|
177 readFolder(folder); |
|
178 else if (name() == QLatin1String("bookmark")) |
|
179 readBookmarkNode(folder); |
|
180 else if (name() == QLatin1String("separator")) |
|
181 readSeparator(folder); |
|
182 else |
|
183 skipCurrentElement(); |
|
184 } |
|
185 } |
|
186 |
|
187 void XbelReader::readTitle(BookmarkNode *parent) |
|
188 { |
|
189 Q_ASSERT(isStartElement() && name() == QLatin1String("title")); |
|
190 parent->title = readElementText(); |
|
191 } |
|
192 |
|
193 void XbelReader::readDescription(BookmarkNode *parent) |
|
194 { |
|
195 Q_ASSERT(isStartElement() && name() == QLatin1String("desc")); |
|
196 parent->desc = readElementText(); |
|
197 } |
|
198 |
|
199 void XbelReader::readSeparator(BookmarkNode *parent) |
|
200 { |
|
201 new BookmarkNode(BookmarkNode::Separator, parent); |
|
202 // empty elements have a start and end element |
|
203 readNext(); |
|
204 } |
|
205 |
|
206 void XbelReader::readBookmarkNode(BookmarkNode *parent) |
|
207 { |
|
208 Q_ASSERT(isStartElement() && name() == QLatin1String("bookmark")); |
|
209 BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark, parent); |
|
210 bookmark->url = attributes().value(QLatin1String("href")).toString(); |
|
211 while (readNextStartElement()) { |
|
212 if (name() == QLatin1String("title")) |
|
213 readTitle(bookmark); |
|
214 else if (name() == QLatin1String("desc")) |
|
215 readDescription(bookmark); |
|
216 else |
|
217 skipCurrentElement(); |
|
218 } |
|
219 if (bookmark->title.isEmpty()) |
|
220 bookmark->title = QObject::tr("Unknown title"); |
|
221 } |
|
222 |
|
223 |
|
224 XbelWriter::XbelWriter() |
|
225 { |
|
226 setAutoFormatting(true); |
|
227 } |
|
228 |
|
229 bool XbelWriter::write(const QString &fileName, const BookmarkNode *root) |
|
230 { |
|
231 QFile file(fileName); |
|
232 if (!root || !file.open(QFile::WriteOnly)) |
|
233 return false; |
|
234 return write(&file, root); |
|
235 } |
|
236 |
|
237 bool XbelWriter::write(QIODevice *device, const BookmarkNode *root) |
|
238 { |
|
239 setDevice(device); |
|
240 |
|
241 writeStartDocument(); |
|
242 writeDTD(QLatin1String("<!DOCTYPE xbel>")); |
|
243 writeStartElement(QLatin1String("xbel")); |
|
244 writeAttribute(QLatin1String("version"), QLatin1String("1.0")); |
|
245 if (root->type() == BookmarkNode::Root) { |
|
246 for (int i = 0; i < root->children().count(); ++i) |
|
247 writeItem(root->children().at(i)); |
|
248 } else { |
|
249 writeItem(root); |
|
250 } |
|
251 |
|
252 writeEndDocument(); |
|
253 return true; |
|
254 } |
|
255 |
|
256 void XbelWriter::writeItem(const BookmarkNode *parent) |
|
257 { |
|
258 switch (parent->type()) { |
|
259 case BookmarkNode::Folder: |
|
260 writeStartElement(QLatin1String("folder")); |
|
261 writeAttribute(QLatin1String("folded"), parent->expanded ? QLatin1String("no") : QLatin1String("yes")); |
|
262 writeTextElement(QLatin1String("title"), parent->title); |
|
263 for (int i = 0; i < parent->children().count(); ++i) |
|
264 writeItem(parent->children().at(i)); |
|
265 writeEndElement(); |
|
266 break; |
|
267 case BookmarkNode::Bookmark: |
|
268 writeStartElement(QLatin1String("bookmark")); |
|
269 if (!parent->url.isEmpty()) |
|
270 writeAttribute(QLatin1String("href"), parent->url); |
|
271 writeTextElement(QLatin1String("title"), parent->title); |
|
272 if (!parent->desc.isEmpty()) |
|
273 writeAttribute(QLatin1String("desc"), parent->desc); |
|
274 writeEndElement(); |
|
275 break; |
|
276 case BookmarkNode::Separator: |
|
277 writeEmptyElement(QLatin1String("separator")); |
|
278 break; |
|
279 default: |
|
280 break; |
|
281 } |
|
282 } |
|
283 |