1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3#include "tracer.h"
4
5#include "xbelsupport.h"
6
7#include "bookmarkitem.h"
8#include "bookmarkmodel.h"
9
10#include <QtCore/QDate>
11#include <QtCore/QModelIndex>
12
13QT_BEGIN_NAMESPACE
14
15struct Bookmark {
16 QString title;
17 QString url;
18 bool folded;
19};
20
21XbelWriter::XbelWriter(BookmarkModel *model)
22 : QXmlStreamWriter()
23 , bookmarkModel(model)
24{
25 TRACE_OBJ
26 setAutoFormatting(true);
27}
28
29void XbelWriter::writeToFile(QIODevice *device)
30{
31 TRACE_OBJ
32 setDevice(device);
33
34 writeStartDocument();
35 writeDTD(dtd: QLatin1String("<!DOCTYPE xbel>"));
36 writeStartElement(qualifiedName: QLatin1String("xbel"));
37 writeAttribute(qualifiedName: QLatin1String("version"), value: QLatin1String("1.0"));
38
39 const QModelIndex root;
40 for (int i = 0; i < bookmarkModel->rowCount(index: root); ++i)
41 writeData(index: bookmarkModel->index(row: i, column: 0, index: root));
42 writeEndDocument();
43}
44
45void XbelWriter::writeData(const QModelIndex &index)
46{
47 TRACE_OBJ
48 if (index.isValid()) {
49 Bookmark entry;
50 entry.title = index.data().toString();
51 entry.url = index.data(arole: UserRoleUrl).toString();
52
53 if (index.data(arole: UserRoleFolder).toBool()) {
54 writeStartElement(qualifiedName: QLatin1String("folder"));
55 entry.folded = !index.data(arole: UserRoleExpanded).toBool();
56 writeAttribute(qualifiedName: QLatin1String("folded"), value: entry.folded
57 ? QLatin1String("yes") : QLatin1String("no"));
58 writeTextElement(qualifiedName: QLatin1String("title"), text: entry.title);
59
60 for (int i = 0; i < bookmarkModel->rowCount(index); ++i)
61 writeData(index: bookmarkModel->index(row: i, column: 0 , index));
62 writeEndElement();
63 } else {
64 writeStartElement(qualifiedName: QLatin1String("bookmark"));
65 writeAttribute(qualifiedName: QLatin1String("href"), value: entry.url);
66 writeTextElement(qualifiedName: QLatin1String("title"), text: entry.title);
67 writeEndElement();
68 }
69 }
70}
71
72// -- XbelReader
73
74XbelReader::XbelReader(BookmarkModel *model)
75 : QXmlStreamReader()
76 , bookmarkModel(model)
77{
78 TRACE_OBJ
79}
80
81bool XbelReader::readFromFile(QIODevice *device)
82{
83 TRACE_OBJ
84 setDevice(device);
85
86 while (!atEnd()) {
87 readNext();
88
89 if (isStartElement()) {
90 if (name() == QLatin1String("xbel")
91 && attributes().value(qualifiedName: QLatin1String("version"))
92 == QLatin1String("1.0")) {
93 const QModelIndex root;
94 parents.append(t: bookmarkModel->addItem(parent: root, isFolder: true));
95 readXBEL();
96 bookmarkModel->setData(index: parents.first(),
97 value: QDate::currentDate().toString(format: Qt::ISODate), role: Qt::EditRole);
98 } else {
99 raiseError(message: QLatin1String("The file is not an XBEL version 1.0 file."));
100 }
101 }
102 }
103
104 return !error();
105}
106
107void XbelReader::readXBEL()
108{
109 TRACE_OBJ
110 while (!atEnd()) {
111 readNext();
112
113 if (isEndElement())
114 break;
115
116 if (isStartElement()) {
117 if (name() == QLatin1String("folder"))
118 readFolder();
119 else if (name() == QLatin1String("bookmark"))
120 readBookmark();
121 else
122 readUnknownElement();
123 }
124 }
125}
126
127void XbelReader::readFolder()
128{
129 TRACE_OBJ
130 parents.append(t: bookmarkModel->addItem(parent: parents.last(), isFolder: true));
131 bookmarkModel->setData(index: parents.last(),
132 value: attributes().value(qualifiedName: QLatin1String("folded")) == QLatin1String("no"),
133 role: UserRoleExpanded);
134
135 while (!atEnd()) {
136 readNext();
137
138 if (isEndElement())
139 break;
140
141 if (isStartElement()) {
142 if (name() == QLatin1String("title")) {
143 bookmarkModel->setData(index: parents.last(), value: readElementText(),
144 role: Qt::EditRole);
145 } else if (name() == QLatin1String("folder"))
146 readFolder();
147 else if (name() == QLatin1String("bookmark"))
148 readBookmark();
149 else
150 readUnknownElement();
151 }
152 }
153
154 parents.removeLast();
155}
156
157void XbelReader::readBookmark()
158{
159 TRACE_OBJ
160 const QModelIndex &index = bookmarkModel->addItem(parent: parents.last(), isFolder: false);
161 if (BookmarkItem* item = bookmarkModel->itemFromIndex(index)) {
162 item->setData(column: UserRoleUrl, value: attributes().value(qualifiedName: QLatin1String("href"))
163 .toString());
164 }
165
166 while (!atEnd()) {
167 readNext();
168
169 if (isEndElement())
170 break;
171
172 if (isStartElement()) {
173 if (name() == QLatin1String("title"))
174 bookmarkModel->setData(index, value: readElementText(), role: Qt::EditRole);
175 else
176 readUnknownElement();
177 }
178 }
179}
180
181void XbelReader::readUnknownElement()
182{
183 TRACE_OBJ
184 while (!atEnd()) {
185 readNext();
186
187 if (isEndElement())
188 break;
189
190 if (isStartElement())
191 readUnknownElement();
192 }
193}
194
195QT_END_NAMESPACE
196

source code of qttools/src/assistant/assistant/xbelsupport.cpp