33 #include <QStringList>
40 #include <QtCore/QUrl>
41 #include <QDataStream>
43 #define NUM_PREFIX "arr_"
45 QString XmlConfig::rootName =
"gcs";
59 if (!domDoc.setContent(&device,
true, &errorStr, &errorLine,
61 QString err = QString(tr(
"GCS config")) +
62 tr(
"Parse error at line %1, column %2:\n%3")
66 qFatal(
"%s",err.toLatin1().data());
69 root = domDoc.documentElement();
70 handleNode(&root, map);
75 void XmlConfig::handleNode(QDomElement* node, QSettings::SettingsMap &map, QString path)
82 QString nodeName = node->nodeName();
85 if ( nodeName.startsWith(NUM_PREFIX) ){
86 nodeName.replace(NUM_PREFIX,
"");
90 nodeName = nodeName.replace(
"__PCT__",
"%");
91 nodeName = QUrl::fromPercentEncoding(nodeName.toLatin1());
93 if ( nodeName == XmlConfig::rootName )
95 else if ( path ==
"" )
98 path +=
"/" + nodeName;
101 for (
int i = 0;
i < node->childNodes().length(); ++
i ){
102 QDomNode child = node->childNodes().item(
i);
103 if ( child.isElement() ){
104 handleNode( static_cast<QDomElement*>(&child), map, path);
106 else if ( child.isText() ){
108 map.insert(path, stringToVariant(node->text()));
111 qDebug() <<
"Child not Element or text!" << child.nodeType();
119 QDomDocument outDocument;
121 outDocument.appendChild( outDocument.createElement(XmlConfig::rootName));
122 QMapIterator<QString, QVariant>
iter(map);
123 while (iter.hasNext()) {
126 QDomNode node = outDocument.firstChild();
127 foreach ( QString elem, iter.key().split(
'/')){
133 elem = QString(QUrl::toPercentEncoding(elem));
134 elem = elem.replace(
"%",
"__PCT__");
137 if ( elem.startsWith(NUM_PREFIX) ){
138 qWarning() <<
"ERROR: Settings must not start with " << NUM_PREFIX
139 <<
" in: " + iter.key();
141 if ( QRegExp(
"[0-9]").exactMatch(elem.left(1)) ){
142 elem.prepend(NUM_PREFIX);
144 if ( node.firstChildElement(elem).isNull() ){
145 node.appendChild(outDocument.createElement(elem));
147 node = node.firstChildElement(elem);
149 node.appendChild(outDocument.createTextNode(variantToString(iter.value())));
151 device.write(outDocument.toByteArray(2).constData());
158 QSettings::SettingsMap XmlConfig::settingsToMap(QSettings& qs){
159 qDebug() <<
"settingsToMap:---------------";
160 QSettings::SettingsMap map;
161 QStringList keys = qs.allKeys();
162 foreach (QString key, keys) {
163 QVariant val = qs.value(key);
164 qDebug() << key << val.toString();
165 map.insert(key, val);
167 qDebug() <<
"settingsToMap End --------";
171 QString XmlConfig::variantToString(
const QVariant &v)
176 case QVariant::Invalid:
177 result = QLatin1String(
"@Invalid()");
180 case QVariant::ByteArray: {
181 QByteArray
a = v.toByteArray().toBase64();
182 result = QLatin1String(
"@ByteArray(");
183 result += QString::fromLatin1(a.constData(), a.size());
184 result += QLatin1Char(
')');
188 case QVariant::String:
189 case QVariant::LongLong:
190 case QVariant::ULongLong:
194 case QVariant::Double:
195 case QVariant::KeySequence:
196 case QVariant::Color: {
197 result = v.toString();
198 if (result.startsWith(QLatin1Char(
'@')))
199 result.prepend(QLatin1Char(
'@'));
202 #ifndef QT_NO_GEOM_VARIANT
203 case QVariant::Rect: {
204 QRect r = qvariant_cast<QRect>(v);
205 result += QLatin1String(
"@Rect(");
206 result += QString::number(r.x());
207 result += QLatin1Char(
' ');
208 result += QString::number(r.y());
209 result += QLatin1Char(
' ');
210 result += QString::number(r.width());
211 result += QLatin1Char(
' ');
212 result += QString::number(r.height());
213 result += QLatin1Char(
')');
216 case QVariant::Size: {
217 QSize
s = qvariant_cast<QSize>(v);
218 result += QLatin1String(
"@Size(");
219 result += QString::number(s.width());
220 result += QLatin1Char(
' ');
221 result += QString::number(s.height());
222 result += QLatin1Char(
')');
225 case QVariant::Point: {
226 QPoint p = qvariant_cast<QPoint>(v);
227 result += QLatin1String(
"@Point(");
228 result += QString::number(p.x());
229 result += QLatin1Char(
' ');
230 result += QString::number(p.y());
231 result += QLatin1Char(
')');
234 #endif // !QT_NO_GEOM_VARIANT
237 #ifndef QT_NO_DATASTREAM
240 QDataStream
s(&a, QIODevice::WriteOnly);
241 s.setVersion(QDataStream::Qt_4_0);
245 result = QLatin1String(
"@Variant(");
246 result += QString::fromLatin1(a.toBase64().constData());
247 result += QLatin1Char(
')');
252 Q_ASSERT(!
"QSettings: Cannot save custom types without QDataStream support");
261 QVariant XmlConfig::stringToVariant(
const QString &s)
263 if (s.startsWith(QLatin1Char(
'@'))) {
264 if (s.endsWith(QLatin1Char(
')'))) {
265 if (s.startsWith(QLatin1String(
"@ByteArray("))) {
266 return QVariant(QByteArray::fromBase64(s.toLatin1().mid(11, s.size() - 12)));
267 }
else if (s.startsWith(QLatin1String(
"@Variant("))) {
268 #ifndef QT_NO_DATASTREAM
269 QByteArray
a(QByteArray::fromBase64(s.toLatin1().mid(9)));
270 QDataStream stream(&a, QIODevice::ReadOnly);
271 stream.setVersion(QDataStream::Qt_4_0);
276 Q_ASSERT(!
"QSettings: Cannot load custom types without QDataStream support");
278 #ifndef QT_NO_GEOM_VARIANT
279 }
else if (s.startsWith(QLatin1String(
"@Rect("))) {
280 QStringList args = splitArgs(s, 5);
281 if (args.size() == 4)
282 return QVariant(QRect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt()));
283 }
else if (s.startsWith(QLatin1String(
"@Size("))) {
284 QStringList args = splitArgs(s, 5);
285 if (args.size() == 2)
286 return QVariant(QSize(args[0].toInt(), args[1].toInt()));
287 }
else if (s.startsWith(QLatin1String(
"@Point("))) {
288 QStringList args = splitArgs(s, 6);
289 if (args.size() == 2)
290 return QVariant(QPoint(args[0].toInt(), args[1].toInt()));
292 }
else if (s == QLatin1String(
"@Invalid()")) {
297 if (s.startsWith(QLatin1String(
"@@")))
298 return QVariant(s.mid(1));
304 QStringList XmlConfig::splitArgs(
const QString &s,
int idx)
308 Q_ASSERT(s.at(idx) == QLatin1Char(
'('));
309 Q_ASSERT(s.at(l - 1) == QLatin1Char(
')'));
314 for (++idx; idx < l; ++
idx) {
316 if (c == QLatin1Char(
')')) {
317 Q_ASSERT(idx == l - 1);
319 }
else if (c == QLatin1Char(
' ')) {
static bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map)
static bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map)
static const QSettings::Format XmlSettingsFormat