1 #include "optionstreereader.h"
2
3 #include <QSize>
4 #include <QRect>
5 #include <QBuffer>
6
7 #include "optionstree.h"
8 #include "varianttree.h"
9
OptionsTreeReader(OptionsTree * options)10 OptionsTreeReader::OptionsTreeReader(OptionsTree* options)
11 : options_(options)
12 {
13 Q_ASSERT(options_);
14 }
15
read(QIODevice * device)16 bool OptionsTreeReader::read(QIODevice* device)
17 {
18 setDevice(device);
19
20 while (!atEnd()) {
21 readNext();
22
23 if (isStartElement()) {
24 readTree(&options_->tree_);
25 }
26 }
27
28 return !error();
29 }
30
readTree(VariantTree * tree)31 void OptionsTreeReader::readTree(VariantTree* tree)
32 {
33 Q_ASSERT(isStartElement());
34 Q_ASSERT(tree);
35
36 while (!atEnd()) {
37 readNext();
38
39 if (isEndElement())
40 break;
41
42 if (isStartElement()) {
43 if (!attributes().value("comment").isEmpty()) {
44 tree->comments_[name().toString()] = attributes().value("comment").toString();
45 }
46
47 if (attributes().value("type").isEmpty()) {
48 if (!tree->trees_.contains(name().toString()))
49 tree->trees_[name().toString()] = new VariantTree(tree);
50 readTree(tree->trees_[name().toString()]);
51 }
52 else {
53 QVariant v = readVariant(attributes().value("type").toString());
54 if (v.isValid()) {
55 tree->values_[name().toString()] = v;
56 }
57 else {
58 tree->unknowns2_[name().toString()] = unknown_;
59 }
60 }
61 }
62 }
63 }
64
readVariant(const QString & type)65 QVariant OptionsTreeReader::readVariant(const QString& type)
66 {
67 QVariant result;
68 if (type == "QStringList") {
69 result = readStringList();
70 }
71 else if (type == "QVariantList") {
72 result = readVariantList();
73 }
74 else if (type == "QSize") {
75 result = readSize();
76 }
77 else if (type == "QRect") {
78 result = readRect();
79 }
80 else if (type == "QByteArray") {
81 result = QByteArray();
82 result = QByteArray::fromBase64(readElementText().toLatin1());
83 }
84 else {
85 QVariant::Type varianttype;
86 bool known = true;
87
88 if (type=="QString") {
89 varianttype = QVariant::String;
90 } else if (type=="bool") {
91 varianttype = QVariant::Bool;
92 } else if (type=="int") {
93 varianttype = QVariant::Int;
94 } else if (type == "QKeySequence") {
95 varianttype = QVariant::KeySequence;
96 } else if (type == "QColor") {
97 varianttype = QVariant::Color;
98 } else {
99 known = false;
100 }
101
102 if (known) {
103 result = readElementText();
104 result.convert(varianttype);
105 }
106 else {
107 QString result;
108 QByteArray ba;
109 QBuffer buffer(&ba);
110 buffer.open(QIODevice::WriteOnly);
111 QXmlStreamWriter writer;
112 writer.setDevice(&buffer);
113
114 writer.writeStartDocument();
115 readUnknownElement(&writer);
116 writer.writeEndDocument();
117 buffer.close();
118
119 // qWarning("ba: %d, '%s'", ba.length(), qPrintable(QString::fromUtf8(ba)));
120 unknown_ = QString::fromUtf8(ba);
121 }
122 }
123 return result;
124 }
125
readStringList()126 QStringList OptionsTreeReader::readStringList()
127 {
128 QStringList list;
129 while (!atEnd()) {
130 readNext();
131
132 if (isEndElement())
133 break;
134
135 if (isStartElement()) {
136 if (name() == "item") {
137 list << readElementText();
138 }
139 }
140 }
141 return list;
142 }
143
readVariantList()144 QVariantList OptionsTreeReader::readVariantList()
145 {
146 QVariantList list;
147 while (!atEnd()) {
148 readNext();
149
150 if (isEndElement())
151 break;
152
153 if (isStartElement()) {
154 if (name() == "item") {
155 list << readVariant(attributes().value("type").toString());
156 }
157 }
158 }
159 return list;
160 }
161
readSize()162 QSize OptionsTreeReader::readSize()
163 {
164 int width = 0, height = 0;
165 while (!atEnd()) {
166 readNext();
167
168 if (isEndElement())
169 break;
170
171 if (isStartElement()) {
172 if (name() == "width") {
173 width = readElementText().toInt();
174 }
175 else if (name() == "height") {
176 height = readElementText().toInt();
177 }
178 }
179 }
180 return QSize(width, height);
181 }
182
readRect()183 QRect OptionsTreeReader::readRect()
184 {
185 int x = 0, y = 0, width = 0, height = 0;
186 while (!atEnd()) {
187 readNext();
188
189 if (isEndElement())
190 break;
191
192 if (isStartElement()) {
193 if (name() == "width") {
194 width = readElementText().toInt();
195 }
196 else if (name() == "height") {
197 height = readElementText().toInt();
198 }
199 else if (name() == "x") {
200 x = readElementText().toInt();
201 }
202 else if (name() == "y") {
203 y = readElementText().toInt();
204 }
205 }
206 }
207 return QRect(x, y, width, height);
208 }
209
readUnknownElement(QXmlStreamWriter * writer)210 void OptionsTreeReader::readUnknownElement(QXmlStreamWriter* writer)
211 {
212 Q_ASSERT(isStartElement());
213 writer->writeStartElement(name().toString());
214 foreach(QXmlStreamAttribute attr, attributes()) {
215 writer->writeAttribute(attr.name().toString(), attr.value().toString());
216 }
217
218 while (!atEnd()) {
219 writer->writeCharacters(text().toString());
220 readNext();
221
222 if (isEndElement())
223 break;
224
225 if (isStartElement())
226 readUnknownElement(writer);
227 }
228
229 writer->writeEndElement();
230 }
231