00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "configloader.h"
00021 #include "private/configloader_p.h"
00022
00023 #include <QColor>
00024 #include <QFont>
00025 #include <QHash>
00026 #include <QXmlContentHandler>
00027 #include <QXmlInputSource>
00028 #include <QXmlSimpleReader>
00029
00030 #include <kdebug.h>
00031 #include <kurl.h>
00032
00033 namespace Plasma
00034 {
00035 class ConfigLoaderHandler : public QXmlDefaultHandler
00036 {
00037 public:
00038 ConfigLoaderHandler(ConfigLoader *config, ConfigLoaderPrivate *d);
00039 bool startElement(const QString &namespaceURI, const QString &localName,
00040 const QString &qName, const QXmlAttributes &atts);
00041 bool endElement(const QString &namespaceURI, const QString &localName,
00042 const QString &qName);
00043 bool characters(const QString &ch);
00044
00045 private:
00046 void addItem();
00047 void resetState();
00048
00049 ConfigLoader *m_config;
00050 ConfigLoaderPrivate *d;
00051 int m_min;
00052 int m_max;
00053 QString m_name;
00054 QString m_key;
00055 QString m_type;
00056 QString m_label;
00057 QString m_default;
00058 QString m_cdata;
00059 QString m_whatsThis;
00060 KConfigSkeleton::ItemEnum::Choice m_choice;
00061 QList<KConfigSkeleton::ItemEnum::Choice> m_enumChoices;
00062 bool m_haveMin;
00063 bool m_haveMax;
00064 bool m_inChoice;
00065 };
00066
00067 void ConfigLoaderPrivate::parse(ConfigLoader *loader, QIODevice *xml)
00068 {
00069 QXmlInputSource source(xml);
00070 QXmlSimpleReader reader;
00071 ConfigLoaderHandler handler(loader, this);
00072 reader.setContentHandler(&handler);
00073 reader.parse(&source, false);
00074 }
00075
00076 ConfigLoaderHandler::ConfigLoaderHandler(ConfigLoader *config, ConfigLoaderPrivate *d)
00077 : QXmlDefaultHandler(),
00078 m_config(config),
00079 d(d)
00080 {
00081 resetState();
00082 }
00083
00084 bool ConfigLoaderHandler::startElement(const QString &namespaceURI, const QString &localName,
00085 const QString &qName, const QXmlAttributes &attrs)
00086 {
00087 Q_UNUSED(namespaceURI)
00088 Q_UNUSED(qName)
00089
00090
00091 int numAttrs = attrs.count();
00092 QString tag = localName.toLower();
00093 if (tag == "group") {
00094 QString group;
00095 for (int i = 0; i < numAttrs; ++i) {
00096 QString name = attrs.localName(i).toLower();
00097 if (name == "name") {
00098
00099 group = attrs.value(i);
00100 }
00101 }
00102 if (group.isEmpty()) {
00103 group = d->baseGroup;
00104 } else {
00105 d->groups.append(group);
00106 if (!d->baseGroup.isEmpty()) {
00107 group = d->baseGroup + '\x1d' + group;
00108 }
00109 }
00110 m_config->setCurrentGroup(group);
00111 } else if (tag == "entry") {
00112 for (int i = 0; i < numAttrs; ++i) {
00113 QString name = attrs.localName(i).toLower();
00114 if (name == "name") {
00115 m_name = attrs.value(i).trimmed();
00116 } else if (name == "type") {
00117 m_type = attrs.value(i).toLower();
00118 } else if (name == "key") {
00119 m_key = attrs.value(i).trimmed();
00120 }
00121 }
00122 } else if (tag == "choice") {
00123 m_choice.name.clear();
00124 m_choice.label.clear();
00125 m_choice.whatsThis.clear();
00126 for (int i = 0; i < numAttrs; ++i) {
00127 QString name = attrs.localName(i).toLower();
00128 if (name == "name") {
00129 m_choice.name = attrs.value(i);
00130 }
00131 }
00132 m_inChoice = true;
00133 }
00134
00135 return true;
00136 }
00137
00138 bool ConfigLoaderHandler::characters(const QString &ch)
00139 {
00140 m_cdata.append(ch);
00141 return true;
00142 }
00143
00144 bool ConfigLoaderHandler::endElement(const QString &namespaceURI,
00145 const QString &localName, const QString &qName)
00146 {
00147 Q_UNUSED(namespaceURI)
00148 Q_UNUSED(qName)
00149
00150
00151 QString tag = localName.toLower();
00152 if (tag == "entry") {
00153 addItem();
00154 resetState();
00155 } else if (tag == "label") {
00156 if (m_inChoice) {
00157 m_choice.label = m_cdata.trimmed();
00158 } else {
00159 m_label = m_cdata.trimmed();
00160 }
00161 } else if (tag == "whatsthis") {
00162 if (m_inChoice) {
00163 m_choice.whatsThis = m_cdata.trimmed();
00164 } else {
00165 m_whatsThis = m_cdata.trimmed();
00166 }
00167 } else if (tag == "default") {
00168 m_default = m_cdata.trimmed();
00169 } else if (tag == "min") {
00170 m_min = m_cdata.toInt(&m_haveMin);
00171 } else if (tag == "max") {
00172 m_max = m_cdata.toInt(&m_haveMax);
00173 } else if (tag == "choice") {
00174 m_enumChoices.append(m_choice);
00175 m_inChoice = false;
00176 }
00177
00178 m_cdata.clear();
00179 return true;
00180 }
00181
00182 void ConfigLoaderHandler::addItem()
00183 {
00184 if (m_name.isEmpty()) {
00185 if (m_key.isEmpty()) {
00186 return;
00187 }
00188
00189 m_name = m_key;
00190 }
00191
00192 m_name.remove(' ');
00193
00194 KConfigSkeletonItem *item = 0;
00195
00196 if (m_type == "bool") {
00197 bool defaultValue = m_default.toLower() == "true";
00198 item = m_config->addItemBool(m_name, *d->newBool(), defaultValue, m_key);
00199 } else if (m_type == "color") {
00200 item = m_config->addItemColor(m_name, *d->newColor(), QColor(m_default), m_key);
00201 } else if (m_type == "datetime") {
00202 item = m_config->addItemDateTime(m_name, *d->newDateTime(),
00203 QDateTime::fromString(m_default), m_key);
00204 } else if (m_type == "enum") {
00205 m_key = (m_key.isEmpty()) ? m_name : m_key;
00206 KConfigSkeleton::ItemEnum *enumItem =
00207 new KConfigSkeleton::ItemEnum(m_config->currentGroup(),
00208 m_key, *d->newInt(),
00209 m_enumChoices,
00210 m_default.toUInt());
00211 m_config->addItem(enumItem, m_name);
00212 item = enumItem;
00213 } else if (m_type == "font") {
00214 item = m_config->addItemFont(m_name, *d->newFont(), QFont(m_default), m_key);
00215 } else if (m_type == "int") {
00216 KConfigSkeleton::ItemInt *intItem = m_config->addItemInt(m_name, *d->newInt(),
00217 m_default.toInt(), m_key);
00218
00219 if (m_haveMin) {
00220 intItem->setMinValue(m_min);
00221 }
00222
00223 if (m_haveMax) {
00224 intItem->setMaxValue(m_max);
00225 }
00226
00227 item = intItem;
00228 } else if (m_type == "password") {
00229 item = m_config->addItemPassword(m_name, *d->newString(), m_default, m_key);
00230 } else if (m_type == "path") {
00231 item = m_config->addItemPath(m_name, *d->newString(), m_default, m_key);
00232 } else if (m_type == "string") {
00233 item = m_config->addItemString(m_name, *d->newString(), m_default, m_key);
00234 } else if (m_type == "stringlist") {
00235
00236 item = m_config->addItemStringList(m_name, *d->newStringList(),
00237 m_default.split(','), m_key);
00238 } else if (m_type == "uint") {
00239 KConfigSkeleton::ItemUInt *uintItem =
00240 m_config->addItemUInt(m_name, *d->newUint(), m_default.toUInt(), m_key);
00241 if (m_haveMin) {
00242 uintItem->setMinValue(m_min);
00243 }
00244 if (m_haveMax) {
00245 uintItem->setMaxValue(m_max);
00246 }
00247 item = uintItem;
00248 } else if (m_type == "url") {
00249 m_key = (m_key.isEmpty()) ? m_name : m_key;
00250 KConfigSkeleton::ItemUrl *urlItem =
00251 new KConfigSkeleton::ItemUrl(m_config->currentGroup(),
00252 m_key, *d->newUrl(),
00253 m_default);
00254 m_config->addItem(urlItem, m_name);
00255 item = urlItem;
00256 } else if (m_type == "double") {
00257 KConfigSkeleton::ItemDouble *doubleItem = m_config->addItemDouble(m_name,
00258 *d->newDouble(), m_default.toDouble(), m_key);
00259 if (m_haveMin) {
00260 doubleItem->setMinValue(m_min);
00261 }
00262 if (m_haveMax) {
00263 doubleItem->setMaxValue(m_max);
00264 }
00265 item = doubleItem;
00266 } else if (m_type == "intlist") {
00267 QStringList tmpList = m_default.split(',');
00268 QList<qint32> defaultList;
00269 foreach (const QString &tmp, tmpList) {
00270 defaultList.append(tmp.toInt());
00271 }
00272 item = m_config->addItemIntList(m_name, *d->newIntList(), defaultList, m_key);
00273 } else if (m_type == "longlong") {
00274 KConfigSkeleton::ItemLongLong *longlongItem = m_config->addItemLongLong(m_name,
00275 *d->newLongLong(), m_default.toLongLong(), m_key);
00276 if (m_haveMin) {
00277 longlongItem->setMinValue(m_min);
00278 }
00279 if (m_haveMax) {
00280 longlongItem->setMaxValue(m_max);
00281 }
00282 item = longlongItem;
00283
00284
00285
00286
00287
00288 } else if (m_type == "point") {
00289 QPoint defaultPoint;
00290 QStringList tmpList = m_default.split(',');
00291 while (tmpList.size() >= 2) {
00292 defaultPoint.setX(tmpList[0].toInt());
00293 defaultPoint.setY(tmpList[1].toInt());
00294 }
00295 item = m_config->addItemPoint(m_name, *d->newPoint(), defaultPoint, m_key);
00296 } else if (m_type == "rect") {
00297 QRect defaultRect;
00298 QStringList tmpList = m_default.split(',');
00299 while (tmpList.size() >= 4) {
00300 defaultRect.setCoords(tmpList[0].toInt(), tmpList[1].toInt(),
00301 tmpList[2].toInt(), tmpList[3].toInt());
00302 }
00303 item = m_config->addItemRect(m_name, *d->newRect(), defaultRect, m_key);
00304 } else if (m_type == "size") {
00305 QSize defaultSize;
00306 QStringList tmpList = m_default.split(',');
00307 while (tmpList.size() >= 2) {
00308 defaultSize.setWidth(tmpList[0].toInt());
00309 defaultSize.setHeight(tmpList[1].toInt());
00310 }
00311 item = m_config->addItemSize(m_name, *d->newSize(), defaultSize, m_key);
00312 } else if (m_type == "ulonglong") {
00313 KConfigSkeleton::ItemULongLong *ulonglongItem =
00314 m_config->addItemULongLong(m_name, *d->newULongLong(), m_default.toULongLong(), m_key);
00315 if (m_haveMin) {
00316 ulonglongItem->setMinValue(m_min);
00317 }
00318 if (m_haveMax) {
00319 ulonglongItem->setMaxValue(m_max);
00320 }
00321 item = ulonglongItem;
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 }
00332
00333 if (item) {
00334 item->setLabel(m_label);
00335 item->setWhatsThis(m_whatsThis);
00336 d->keysToNames.insert(item->group() + item->key(), item->name());
00337 }
00338 }
00339
00340 void ConfigLoaderHandler::resetState()
00341 {
00342 m_haveMin = false;
00343 m_min = 0;
00344 m_haveMax = false;
00345 m_max = 0;
00346 m_name.clear();
00347 m_type.clear();
00348 m_label.clear();
00349 m_default.clear();
00350 m_key.clear();
00351 m_whatsThis.clear();
00352 m_enumChoices.clear();
00353 m_inChoice = false;
00354 }
00355
00356 ConfigLoader::ConfigLoader(const QString &configFile, QIODevice *xml, QObject *parent)
00357 : KConfigSkeleton(configFile, parent),
00358 d(new ConfigLoaderPrivate)
00359 {
00360 d->parse(this, xml);
00361 }
00362
00363 ConfigLoader::ConfigLoader(KSharedConfigPtr config, QIODevice *xml, QObject *parent)
00364 : KConfigSkeleton(config, parent),
00365 d(new ConfigLoaderPrivate)
00366 {
00367 d->parse(this, xml);
00368 }
00369
00370
00371
00372
00373 ConfigLoader::ConfigLoader(const KConfigGroup *config, QIODevice *xml, QObject *parent)
00374 : KConfigSkeleton(KSharedConfig::openConfig(config->config()->name()), parent),
00375 d(new ConfigLoaderPrivate)
00376 {
00377 KConfigGroup group = config->parent();
00378 d->baseGroup = config->name();
00379 while (group.isValid() && group.name() != "<default>") {
00380 d->baseGroup = group.name() + '\x1d' + d->baseGroup;
00381 group = group.parent();
00382 }
00383 d->parse(this, xml);
00384 }
00385
00386 ConfigLoader::~ConfigLoader()
00387 {
00388 delete d;
00389 }
00390
00391 KConfigSkeletonItem *ConfigLoader::findItem(const QString &group, const QString &key)
00392 {
00393 return KConfigSkeleton::findItem(d->keysToNames[group + key]);
00394 }
00395
00396 KConfigSkeletonItem *ConfigLoader::findItemByName(const QString &name)
00397 {
00398 return KConfigSkeleton::findItem(name);
00399 }
00400
00401 QVariant ConfigLoader::property(const QString &name)
00402 {
00403 KConfigSkeletonItem *item = KConfigSkeleton::findItem(name);
00404
00405 if (item) {
00406 return item->property();
00407 }
00408
00409 return QVariant();
00410 }
00411
00412 bool ConfigLoader::hasGroup(const QString &group) const
00413 {
00414 return d->groups.contains(group);
00415 }
00416
00417 QStringList ConfigLoader::groupList() const
00418 {
00419 return d->groups;
00420 }
00421
00422 void ConfigLoader::usrWriteConfig()
00423 {
00424 if (d->saveDefaults) {
00425 KConfigSkeletonItem::List itemList = items();
00426 for(int i = 0; i < itemList.size(); i++) {
00427 KConfigGroup cg(config(), itemList.at(i)->group());
00428 cg.writeEntry(itemList.at(i)->key(), "");
00429 }
00430 }
00431 }
00432
00433 }