00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "configxml.h"
00021
00022 #include <QColor>
00023 #include <QFont>
00024 #include <QXmlContentHandler>
00025 #include <QXmlInputSource>
00026 #include <QXmlSimpleReader>
00027
00028 #include <KDebug>
00029 #include <KUrl>
00030
00031 namespace Plasma
00032 {
00033
00034 class ConfigXmlPrivate
00035 {
00036 public:
00037 ~ConfigXmlPrivate()
00038 {
00039 qDeleteAll(bools);
00040 qDeleteAll(strings);
00041 qDeleteAll(stringlists);
00042 qDeleteAll(colors);
00043 qDeleteAll(fonts);
00044 qDeleteAll(ints);
00045 qDeleteAll(uints);
00046 qDeleteAll(urls);
00047 qDeleteAll(dateTimes);
00048 qDeleteAll(doubles);
00049 qDeleteAll(intlists);
00050 qDeleteAll(longlongs);
00051 qDeleteAll(points);
00052 qDeleteAll(rects);
00053 qDeleteAll(sizes);
00054 qDeleteAll(ulonglongs);
00055 qDeleteAll(urllists);
00056 }
00057
00058 bool* newBool()
00059 {
00060 bool* v = new bool;
00061 bools.append(v);
00062 return v;
00063 }
00064
00065 QString* newString()
00066 {
00067 QString* v = new QString;
00068 strings.append(v);
00069 return v;
00070 }
00071
00072 QStringList* newStringList()
00073 {
00074 QStringList* v = new QStringList;
00075 stringlists.append(v);
00076 return v;
00077 }
00078
00079 QColor* newColor()
00080 {
00081 QColor* v = new QColor;
00082 colors.append(v);
00083 return v;
00084 }
00085
00086 QFont* newFont()
00087 {
00088 QFont* v = new QFont;
00089 fonts.append(v);
00090 return v;
00091 }
00092
00093 qint32* newInt()
00094 {
00095 qint32* v = new qint32;
00096 ints.append(v);
00097 return v;
00098 }
00099
00100 quint32* newUint()
00101 {
00102 quint32* v = new quint32;
00103 uints.append(v);
00104 return v;
00105 }
00106
00107 KUrl* newUrl()
00108 {
00109 KUrl* v = new KUrl;
00110 urls.append(v);
00111 return v;
00112 }
00113
00114 QDateTime* newDateTime()
00115 {
00116 QDateTime* v = new QDateTime;
00117 dateTimes.append(v);
00118 return v;
00119 }
00120
00121 double* newDouble()
00122 {
00123 double* v = new double;
00124 doubles.append(v);
00125 return v;
00126 }
00127
00128 QList<qint32>* newIntList()
00129 {
00130 QList<qint32>* v = new QList<qint32>;
00131 intlists.append(v);
00132 return v;
00133 }
00134
00135 qint64* newLongLong()
00136 {
00137 qint64* v = new qint64;
00138 longlongs.append(v);
00139 return v;
00140 }
00141
00142 QPoint* newPoint()
00143 {
00144 QPoint* v = new QPoint;
00145 points.append(v);
00146 return v;
00147 }
00148
00149 QRect* newRect()
00150 {
00151 QRect* v = new QRect;
00152 rects.append(v);
00153 return v;
00154 }
00155
00156 QSize* newSize()
00157 {
00158 QSize* v = new QSize;
00159 sizes.append(v);
00160 return v;
00161 }
00162
00163 quint64* newULongLong()
00164 {
00165 quint64* v = new quint64;
00166 ulonglongs.append(v);
00167 return v;
00168 }
00169
00170 KUrl::List* newUrlList()
00171 {
00172 KUrl::List* v = new KUrl::List;
00173 urllists.append(v);
00174 return v;
00175 }
00176
00177 void parse(ConfigXml *configXml, QIODevice *xml);
00178
00179 QList<bool*> bools;
00180 QList<QString*> strings;
00181 QList<QStringList*> stringlists;
00182 QList<QColor*> colors;
00183 QList<QFont*> fonts;
00184 QList<qint32*> ints;
00185 QList<quint32*> uints;
00186 QList<KUrl*> urls;
00187 QList<QDateTime*> dateTimes;
00188 QList<double*> doubles;
00189 QList<QList<qint32>*> intlists;
00190 QList<qint64*> longlongs;
00191 QList<QPoint*> points;
00192 QList<QRect*> rects;
00193 QList<QSize*> sizes;
00194 QList<quint64*> ulonglongs;
00195 QList<KUrl::List*> urllists;
00196 QMap<QString, QString> keysToNames;
00197 };
00198
00199 class ConfigXmlHandler : public QXmlDefaultHandler
00200 {
00201 public:
00202 ConfigXmlHandler(ConfigXml* config, ConfigXmlPrivate* d);
00203 bool startElement(const QString &namespaceURI, const QString & localName, const QString &qName, const QXmlAttributes &atts);
00204 bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName);
00205 bool characters(const QString &ch);
00206
00207 private:
00208 void addItem();
00209 void resetState();
00210
00211 ConfigXml* m_config;
00212 ConfigXmlPrivate* d;
00213 int m_min;
00214 int m_max;
00215 QString m_name;
00216 QString m_key;
00217 QString m_type;
00218 QString m_label;
00219 QString m_default;
00220 QString m_cdata;
00221 QString m_whatsThis;
00222 KConfigSkeleton::ItemEnum::Choice m_choice;
00223 QList<KConfigSkeleton::ItemEnum::Choice> m_enumChoices;
00224 bool m_haveMin;
00225 bool m_haveMax;
00226 bool m_inChoice;
00227 };
00228
00229 void ConfigXmlPrivate::parse(ConfigXml *configXml, QIODevice *xml)
00230 {
00231 QXmlInputSource source(xml);
00232 QXmlSimpleReader reader;
00233 ConfigXmlHandler handler(configXml, this);
00234 reader.setContentHandler(&handler);
00235 reader.parse(&source, false);
00236 }
00237
00238 ConfigXmlHandler::ConfigXmlHandler(ConfigXml* config, ConfigXmlPrivate* d)
00239 : QXmlDefaultHandler(),
00240 m_config(config),
00241 d(d)
00242 {
00243 resetState();
00244 }
00245
00246 bool ConfigXmlHandler::startElement(const QString &namespaceURI, const QString &localName,
00247 const QString &qName, const QXmlAttributes &attrs)
00248 {
00249 Q_UNUSED(namespaceURI)
00250 Q_UNUSED(qName)
00251
00252
00253 int numAttrs = attrs.count();
00254 QString tag = localName.toLower();
00255 if (tag == "group") {
00256 for (int i = 0; i < numAttrs; ++i) {
00257 QString name = attrs.localName(i).toLower();
00258 if (name == "name") {
00259 kDebug() << "set group to " << attrs.value(i);
00260 m_config->setCurrentGroup(attrs.value(i));
00261 }
00262 }
00263 } else if (tag == "entry") {
00264 for (int i = 0; i < numAttrs; ++i) {
00265 QString name = attrs.localName(i).toLower();
00266 if (name == "name") {
00267 m_name = attrs.value(i);
00268 } else if (name == "type") {
00269 m_type = attrs.value(i).toLower();
00270 } else if (name == "key") {
00271 m_key = attrs.value(i);
00272 }
00273 }
00274 } else if (tag == "choice") {
00275 m_choice.name.clear();
00276 m_choice.label.clear();
00277 m_choice.whatsThis.clear();
00278 for (int i = 0; i < numAttrs; ++i) {
00279 QString name = attrs.localName(i).toLower();
00280 if (name == "name") {
00281 m_choice.name = attrs.value(i);
00282 }
00283 }
00284 m_inChoice = true;
00285 }
00286
00287 return true;
00288 }
00289
00290 bool ConfigXmlHandler::characters(const QString &ch)
00291 {
00292 m_cdata.append(ch);
00293 return true;
00294 }
00295
00296 bool ConfigXmlHandler::endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
00297 {
00298 Q_UNUSED(namespaceURI)
00299 Q_UNUSED(qName)
00300
00301
00302 QString tag = localName.toLower();
00303 if (tag == "entry") {
00304 addItem();
00305 resetState();
00306 } else if (tag == "label") {
00307 if (m_inChoice) {
00308 m_choice.label = m_cdata;
00309 } else {
00310 m_label = m_cdata;
00311 }
00312 } else if (tag == "whatsthis") {
00313 if (m_inChoice) {
00314 m_choice.whatsThis = m_cdata;
00315 } else {
00316 m_whatsThis = m_cdata;
00317 }
00318 } else if (tag == "default") {
00319 m_default = m_cdata;
00320 } else if (tag == "min") {
00321 m_min = m_cdata.toInt(&m_haveMin);
00322 } else if (tag == "max") {
00323 m_max = m_cdata.toInt(&m_haveMax);
00324 } else if (tag == "choice") {
00325 m_enumChoices.append(m_choice);
00326 m_inChoice = false;
00327 }
00328
00329 m_cdata.clear();
00330 return true;
00331 }
00332
00333 void ConfigXmlHandler::addItem()
00334 {
00335 if (m_name.isEmpty()) {
00336 return;
00337 }
00338
00339 KConfigSkeletonItem* item = 0;
00340
00341 if (m_type == "bool") {
00342 bool defaultValue = m_default.toLower() == "true";
00343 item = m_config->addItemBool(m_name, *d->newBool(), defaultValue, m_key);
00344 } else if (m_type == "color") {
00345 item = m_config->addItemColor(m_name, *d->newColor(), QColor(m_default), m_key);
00346 } else if (m_type == "datetime") {
00347 item = m_config->addItemDateTime(m_name, *d->newDateTime(),
00348 QDateTime::fromString(m_default), m_key);
00349 } else if (m_type == "enum") {
00350 KConfigSkeleton::ItemEnum* enumItem =
00351 new KConfigSkeleton::ItemEnum(m_config->currentGroup(),
00352 m_key, *d->newInt(),
00353 m_enumChoices,
00354 m_default.toUInt());
00355 enumItem->setName(m_name);
00356 m_config->addItem(enumItem, m_name);
00357 item = enumItem;
00358 } else if (m_type == "font") {
00359 item = m_config->addItemFont(m_name, *d->newFont(), QFont(m_default), m_key);
00360 } else if (m_type == "int") {
00361 KConfigSkeleton::ItemInt* intItem = m_config->addItemInt(m_name,
00362 *d->newInt(),
00363 m_default.toInt(),
00364 m_key);
00365 if (m_haveMin) {
00366 intItem->setMinValue(m_min);
00367 }
00368 if (m_haveMax) {
00369 intItem->setMaxValue(m_max);
00370 }
00371 item = intItem;
00372 } else if (m_type == "password") {
00373 item = m_config->addItemPassword(m_name, *d->newString(), m_default, m_key);
00374 } else if (m_type == "path") {
00375 item = m_config->addItemPath(m_name, *d->newString(), m_default, m_key);
00376 } else if (m_type == "string") {
00377 item = m_config->addItemString(m_name, *d->newString(), m_default, m_key);
00378 } else if (m_type == "stringlist") {
00379
00380 item = m_config->addItemStringList(m_name, *d->newStringList(), m_default.split(","), m_key);
00381 } else if (m_type == "uint") {
00382 KConfigSkeleton::ItemUInt* uintItem = m_config->addItemUInt(m_name,
00383 *d->newUint(),
00384 m_default.toUInt(),
00385 m_key);
00386 if (m_haveMin) {
00387 uintItem->setMinValue(m_min);
00388 }
00389 if (m_haveMax) {
00390 uintItem->setMaxValue(m_max);
00391 }
00392 item = uintItem;
00393 } else if (m_type == "url") {
00394 KConfigSkeleton::ItemUrl* urlItem =
00395 new KConfigSkeleton::ItemUrl(m_config->currentGroup(),
00396 m_key, *d->newUrl(),
00397 m_default);
00398 urlItem->setName(m_name);
00399 m_config->addItem(urlItem, m_name);
00400 item = urlItem;
00401 } else if (m_type == "double") {
00402 KConfigSkeleton::ItemDouble* doubleItem = m_config->addItemDouble(m_name,
00403 *d->newDouble(), m_default.toDouble(), m_key);
00404 if (m_haveMin) {
00405 doubleItem->setMinValue(m_min);
00406 }
00407 if (m_haveMax) {
00408 doubleItem->setMaxValue(m_max);
00409 }
00410 item = doubleItem;
00411 } else if (m_type == "intlist") {
00412 QStringList tmpList = m_default.split(",");
00413 QList<qint32> defaultList;
00414 foreach (const QString &tmp, tmpList) {
00415 defaultList.append(tmp.toInt());
00416 }
00417 item = m_config->addItemIntList(m_name, *d->newIntList(), defaultList, m_key);
00418 } else if (m_type == "longlong") {
00419 KConfigSkeleton::ItemLongLong* longlongItem = m_config->addItemLongLong(m_name,
00420 *d->newLongLong(), m_default.toLongLong(), m_key);
00421 if (m_haveMin) {
00422 longlongItem->setMinValue(m_min);
00423 }
00424 if (m_haveMax) {
00425 longlongItem->setMaxValue(m_max);
00426 }
00427 item = longlongItem;
00428
00429
00430
00431
00432 } else if (m_type == "point") {
00433 QPoint defaultPoint;
00434 QStringList tmpList = m_default.split(",");
00435 while (tmpList.size() >= 2) {
00436 defaultPoint.setX(tmpList[0].toInt());
00437 defaultPoint.setY(tmpList[1].toInt());
00438 }
00439 item = m_config->addItemPoint(m_name, *d->newPoint(), defaultPoint, m_key);
00440 } else if (m_type == "rect") {
00441 QRect defaultRect;
00442 QStringList tmpList = m_default.split(",");
00443 while (tmpList.size() >= 4) {
00444 defaultRect.setCoords(tmpList[0].toInt(), tmpList[1].toInt(),
00445 tmpList[2].toInt(), tmpList[3].toInt());
00446 }
00447 item = m_config->addItemRect(m_name, *d->newRect(), defaultRect, m_key);
00448 } else if (m_type == "size") {
00449 QSize defaultSize;
00450 QStringList tmpList = m_default.split(",");
00451 while (tmpList.size() >= 2) {
00452 defaultSize.setWidth(tmpList[0].toInt());
00453 defaultSize.setHeight(tmpList[1].toInt());
00454 }
00455 item = m_config->addItemSize(m_name, *d->newSize(), defaultSize, m_key);
00456 } else if (m_type == "ulonglong") {
00457 KConfigSkeleton::ItemULongLong* ulonglongItem = m_config->addItemULongLong(m_name,
00458 *d->newULongLong(), m_default.toULongLong(), m_key);
00459 if (m_haveMin) {
00460 ulonglongItem->setMinValue(m_min);
00461 }
00462 if (m_haveMax) {
00463 ulonglongItem->setMaxValue(m_max);
00464 }
00465 item = ulonglongItem;
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 }
00476
00477 if (item) {
00478 item->setLabel(m_label);
00479 item->setWhatsThis(m_whatsThis);
00480 d->keysToNames.insert(item->group() + item->key(), item->name());
00481 }
00482 }
00483
00484 void ConfigXmlHandler::resetState()
00485 {
00486 m_haveMin = false;
00487 m_min = 0;
00488 m_haveMax = false;
00489 m_max = 0;
00490 m_name.clear();
00491 m_type.clear();
00492 m_label.clear();
00493 m_default.clear();
00494 m_key.clear();
00495 m_whatsThis.clear();
00496 m_enumChoices.clear();
00497 m_inChoice = false;
00498 }
00499
00500 ConfigXml::ConfigXml(const QString &configFile, QIODevice *xml, QObject *parent)
00501 : KConfigSkeleton(configFile, parent),
00502 d(new ConfigXmlPrivate)
00503 {
00504 QXmlInputSource source(xml);
00505 QXmlSimpleReader reader;
00506 ConfigXmlHandler handler(this, d);
00507 reader.setContentHandler(&handler);
00508 reader.parse(&source, false);
00509 }
00510
00511 ConfigXml::ConfigXml(KSharedConfigPtr config, QIODevice *xml, QObject *parent)
00512 : KConfigSkeleton(config, parent),
00513 d(new ConfigXmlPrivate)
00514 {
00515 d->parse(this, xml);
00516 }
00517
00518
00519
00520
00521 ConfigXml::ConfigXml(const KConfigGroup *config, QIODevice *xml, QObject *parent)
00522 : KConfigSkeleton(KSharedConfig::openConfig(config->config()->name()), parent),
00523 d(new ConfigXmlPrivate)
00524 {
00525 d->parse(this, xml);
00526 }
00527
00528 ConfigXml::~ConfigXml()
00529 {
00530 delete d;
00531 }
00532
00533 KConfigSkeletonItem* ConfigXml::findItem(const QString &group, const QString &key)
00534 {
00535 return KConfigSkeleton::findItem(d->keysToNames[group + key]);
00536 }
00537
00538 }