2 * Copyright 2007 Aaron Seigo <aseigo@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "configxml.h"
24 #include <QXmlContentHandler>
25 #include <QXmlInputSource>
26 #include <QXmlSimpleReader>
34 class ConfigXml::Private
41 qDeleteAll(stringlists
);
47 qDeleteAll(dateTimes
);
50 qDeleteAll(longlongs
);
54 qDeleteAll(ulonglongs
);
67 QString
* v
= new QString
;
72 QStringList
* newStringList()
74 QStringList
* v
= new QStringList
;
75 stringlists
.append(v
);
81 QColor
* v
= new QColor
;
95 qint32
* v
= new qint32
;
102 quint32
* v
= new quint32
;
114 QDateTime
* newDateTime()
116 QDateTime
* v
= new QDateTime
;
123 double* v
= new double;
128 QList
<qint32
>* newIntList()
130 QList
<qint32
>* v
= new QList
<qint32
>;
135 qint64
* newLongLong()
137 qint64
* v
= new qint64
;
144 QPoint
* v
= new QPoint
;
151 QRect
* v
= new QRect
;
158 QSize
* v
= new QSize
;
163 quint64
* newULongLong()
165 quint64
* v
= new quint64
;
166 ulonglongs
.append(v
);
170 KUrl::List
* newUrlList()
172 KUrl::List
* v
= new KUrl::List
;
177 void parse(ConfigXml
*configXml
, QIODevice
*xml
);
180 QList
<QString
*> strings
;
181 QList
<QStringList
*> stringlists
;
182 QList
<QColor
*> colors
;
185 QList
<quint32
*> uints
;
187 QList
<QDateTime
*> dateTimes
;
188 QList
<double*> doubles
;
189 QList
<QList
<qint32
>*> intlists
;
190 QList
<qint64
*> longlongs
;
191 QList
<QPoint
*> points
;
194 QList
<quint64
*> ulonglongs
;
195 QList
<KUrl::List
*> urllists
;
198 class ConfigXmlHandler
: public QXmlDefaultHandler
201 ConfigXmlHandler(ConfigXml
* config
, ConfigXml::Private
* d
);
202 bool startElement(const QString
&namespaceURI
, const QString
& localName
, const QString
&qName
, const QXmlAttributes
&atts
);
203 bool endElement(const QString
&namespaceURI
, const QString
&localName
, const QString
&qName
);
204 bool characters(const QString
&ch
);
211 ConfigXml::Private
* d
;
221 KConfigSkeleton::ItemEnum::Choice m_choice
;
222 QList
<KConfigSkeleton::ItemEnum::Choice
> m_enumChoices
;
228 void ConfigXml::Private::parse(ConfigXml
*configXml
, QIODevice
*xml
)
230 QXmlInputSource
source(xml
);
231 QXmlSimpleReader reader
;
232 ConfigXmlHandler
handler(configXml
, this);
233 reader
.setContentHandler(&handler
);
234 reader
.parse(&source
, false);
237 ConfigXmlHandler::ConfigXmlHandler(ConfigXml
* config
, ConfigXml::Private
* d
)
238 : QXmlDefaultHandler(),
245 bool ConfigXmlHandler::startElement(const QString
&namespaceURI
, const QString
&localName
,
246 const QString
&qName
, const QXmlAttributes
&attrs
)
248 Q_UNUSED(namespaceURI
)
251 // kDebug() << "ConfigXmlHandler::startElement(" << localName << qName;
252 int numAttrs
= attrs
.count();
253 QString tag
= localName
.toLower();
254 if (tag
== "group") {
255 for (int i
= 0; i
< numAttrs
; ++i
) {
256 QString name
= attrs
.localName(i
).toLower();
257 if (name
== "name") {
258 kDebug() << "set group to " << attrs
.value(i
);
259 m_config
->setCurrentGroup(attrs
.value(i
));
262 } else if (tag
== "entry") {
263 for (int i
= 0; i
< numAttrs
; ++i
) {
264 QString name
= attrs
.localName(i
).toLower();
265 if (name
== "name") {
266 m_name
= attrs
.value(i
);
267 } else if (name
== "type") {
268 m_type
= attrs
.value(i
).toLower();
269 } else if (name
== "key") {
270 m_key
= attrs
.value(i
);
273 } else if (tag
== "choice") {
274 m_choice
.name
.clear();
275 m_choice
.label
.clear();
276 m_choice
.whatsThis
.clear();
277 for (int i
= 0; i
< numAttrs
; ++i
) {
278 QString name
= attrs
.localName(i
).toLower();
279 if (name
== "name") {
280 m_choice
.name
= attrs
.value(i
);
289 bool ConfigXmlHandler::characters(const QString
&ch
)
295 bool ConfigXmlHandler::endElement(const QString
&namespaceURI
, const QString
&localName
, const QString
&qName
)
297 Q_UNUSED(namespaceURI
)
300 // kDebug() << "ConfigXmlHandler::endElement(" << localName << qName;
301 QString tag
= localName
.toLower();
302 if (tag
== "entry") {
305 } else if (tag
== "label") {
307 m_choice
.label
= m_cdata
;
311 } else if (tag
== "whatsthis") {
313 m_choice
.whatsThis
= m_cdata
;
315 m_whatsThis
= m_cdata
;
317 } else if (tag
== "default") {
319 } else if (tag
== "min") {
320 m_min
= m_cdata
.toInt(&m_haveMin
);
321 } else if (tag
== "max") {
322 m_max
= m_cdata
.toInt(&m_haveMax
);
323 } else if (tag
== "choice") {
324 m_enumChoices
.append(m_choice
);
332 void ConfigXmlHandler::addItem()
334 if (m_name
.isEmpty()) {
338 KConfigSkeletonItem
* item
= 0;
340 if (m_type
== "bool") {
341 bool defaultValue
= m_default
.toLower() == "true";
342 item
= m_config
->addItemBool(m_name
, *d
->newBool(), defaultValue
, m_key
);
343 } else if (m_type
== "color") {
344 item
= m_config
->addItemColor(m_name
, *d
->newColor(), QColor(m_default
), m_key
);
345 } else if (m_type
== "datetime") {
346 item
= m_config
->addItemDateTime(m_name
, *d
->newDateTime(),
347 QDateTime::fromString(m_default
), m_key
);
348 } else if (m_type
== "enum") {
349 KConfigSkeleton::ItemEnum
* enumItem
=
350 new KConfigSkeleton::ItemEnum(m_config
->currentGroup(),
354 enumItem
->setName(m_name
);
355 m_config
->addItem(enumItem
, m_name
);
357 } else if (m_type
== "font") {
358 item
= m_config
->addItemFont(m_name
, *d
->newFont(), QFont(m_default
), m_key
);
359 } else if (m_type
== "int") {
360 KConfigSkeleton::ItemInt
* intItem
= m_config
->addItemInt(m_name
,
365 intItem
->setMinValue(m_min
);
368 intItem
->setMaxValue(m_max
);
371 } else if (m_type
== "password") {
372 item
= m_config
->addItemPassword(m_name
, *d
->newString(), m_default
, m_key
);
373 } else if (m_type
== "path") {
374 item
= m_config
->addItemPath(m_name
, *d
->newString(), m_default
, m_key
);
375 } else if (m_type
== "string") {
376 item
= m_config
->addItemString(m_name
, *d
->newString(), m_default
, m_key
);
377 } else if (m_type
== "stringlist") {
378 //FIXME: the split() is naive and will break on lists with ,'s in them
379 item
= m_config
->addItemStringList(m_name
, *d
->newStringList(), m_default
.split(","), m_key
);
380 } else if (m_type
== "uint") {
381 KConfigSkeleton::ItemUInt
* uintItem
= m_config
->addItemUInt(m_name
,
386 uintItem
->setMinValue(m_min
);
389 uintItem
->setMaxValue(m_max
);
392 } else if (m_type
== "url") {
393 KConfigSkeleton::ItemUrl
* urlItem
=
394 new KConfigSkeleton::ItemUrl(m_config
->currentGroup(),
397 urlItem
->setName(m_name
);
398 m_config
->addItem(urlItem
, m_name
);
400 } else if (m_type
== "double") {
401 KConfigSkeleton::ItemDouble
* doubleItem
= m_config
->addItemDouble(m_name
,
402 *d
->newDouble(), m_default
.toDouble(), m_key
);
404 doubleItem
->setMinValue(m_min
);
407 doubleItem
->setMaxValue(m_max
);
410 } else if (m_type
== "intlist") {
411 QStringList tmpList
= m_default
.split(",");
412 QList
<qint32
> defaultList
;
413 foreach (QString tmp
, tmpList
) {
414 defaultList
.append(tmp
.toInt());
416 item
= m_config
->addItemIntList(m_name
, *d
->newIntList(), defaultList
, m_key
);
417 } else if (m_type
== "longlong") {
418 KConfigSkeleton::ItemLongLong
* longlongItem
= m_config
->addItemLongLong(m_name
,
419 *d
->newLongLong(), m_default
.toLongLong(), m_key
);
421 longlongItem
->setMinValue(m_min
);
424 longlongItem
->setMaxValue(m_max
);
427 /* No addItemPathList in KConfigSkeleton ?
428 } else if (m_type == "PathList") {
429 //FIXME: the split() is naive and will break on lists with ,'s in them
430 item = m_config->addItemPathList(m_name, *d->newStringList(), m_default.split(","), m_key); */
431 } else if (m_type
== "point") {
433 QStringList tmpList
= m_default
.split(",");
434 while (tmpList
.size() >= 2) {
435 defaultPoint
.setX(tmpList
[0].toInt());
436 defaultPoint
.setY(tmpList
[1].toInt());
438 item
= m_config
->addItemPoint(m_name
, *d
->newPoint(), defaultPoint
, m_key
);
439 } else if (m_type
== "rect") {
441 QStringList tmpList
= m_default
.split(",");
442 while (tmpList
.size() >= 4) {
443 defaultRect
.setCoords(tmpList
[0].toInt(), tmpList
[1].toInt(),
444 tmpList
[2].toInt(), tmpList
[3].toInt());
446 item
= m_config
->addItemRect(m_name
, *d
->newRect(), defaultRect
, m_key
);
447 } else if (m_type
== "size") {
449 QStringList tmpList
= m_default
.split(",");
450 while (tmpList
.size() >= 2) {
451 defaultSize
.setWidth(tmpList
[0].toInt());
452 defaultSize
.setHeight(tmpList
[1].toInt());
454 item
= m_config
->addItemSize(m_name
, *d
->newSize(), defaultSize
, m_key
);
455 } else if (m_type
== "ulonglong") {
456 KConfigSkeleton::ItemULongLong
* ulonglongItem
= m_config
->addItemULongLong(m_name
,
457 *d
->newULongLong(), m_default
.toULongLong(), m_key
);
459 ulonglongItem
->setMinValue(m_min
);
462 ulonglongItem
->setMaxValue(m_max
);
464 item
= ulonglongItem
;
465 /* No addItemUrlList in KConfigSkeleton ?
466 } else if (m_type == "urllist") {
467 //FIXME: the split() is naive and will break on lists with ,'s in them
468 QStringList tmpList = m_default.split(",");
469 KUrl::List defaultList;
470 foreach (QString tmp, tmpList) {
471 defaultList.append(KUrl(tmp));
473 item = m_config->addItemUrlList(m_name, *d->newUrlList(), defaultList, m_key);*/
477 item
->setLabel(m_label
);
478 item
->setWhatsThis(m_whatsThis
);
482 void ConfigXmlHandler::resetState()
494 m_enumChoices
.clear();
498 ConfigXml::ConfigXml(const QString
&configFile
, QIODevice
*xml
, QObject
*parent
)
499 : KConfigSkeleton(configFile
, parent
),
502 QXmlInputSource
source(xml
);
503 QXmlSimpleReader reader
;
504 ConfigXmlHandler
handler(this, d
);
505 reader
.setContentHandler(&handler
);
506 reader
.parse(&source
, false);
509 ConfigXml::ConfigXml(KSharedConfigPtr config
, QIODevice
*xml
, QObject
*parent
)
510 : KConfigSkeleton(config
, parent
),
516 //FIXME: obviously this is broken and should be using the group as the root,
517 // but KConfigSkeleton does not currently support this. it will eventually though,
518 // at which point this can be addressed properly
519 ConfigXml::ConfigXml(const KConfigGroup
*config
, QIODevice
*xml
, QObject
*parent
)
520 : KConfigSkeleton(KSharedConfig::openConfig(config
->config()->name()), parent
),
526 ConfigXml::~ConfigXml()
531 } // Plasma namespace