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);
00116 } else if (name == "type") {
00117 m_type = attrs.value(i).toLower();
00118 } else if (name == "key") {
00119 m_key = attrs.value(i);
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 return;
00186 }
00187
00188 KConfigSkeletonItem *item = 0;
00189
00190 if (m_type == "bool") {
00191 bool defaultValue = m_default.toLower() == "true";
00192 item = m_config->addItemBool(m_name, *d->newBool(), defaultValue, m_key);
00193 } else if (m_type == "color") {
00194 item = m_config->addItemColor(m_name, *d->newColor(), QColor(m_default), m_key);
00195 } else if (m_type == "datetime") {
00196 item = m_config->addItemDateTime(m_name, *d->newDateTime(),
00197 QDateTime::fromString(m_default), m_key);
00198 } else if (m_type == "enum") {
00199 m_key = (m_key.isEmpty()) ? m_name : m_key;
00200 KConfigSkeleton::ItemEnum *enumItem =
00201 new KConfigSkeleton::ItemEnum(m_config->currentGroup(),
00202 m_key, *d->newInt(),
00203 m_enumChoices,
00204 m_default.toUInt());
00205 m_config->addItem(enumItem, m_name);
00206 item = enumItem;
00207 } else if (m_type == "font") {
00208 item = m_config->addItemFont(m_name, *d->newFont(), QFont(m_default), m_key);
00209 } else if (m_type == "int") {
00210 KConfigSkeleton::ItemInt *intItem = m_config->addItemInt(m_name, *d->newInt(),
00211 m_default.toInt(), m_key);
00212
00213 if (m_haveMin) {
00214 intItem->setMinValue(m_min);
00215 }
00216
00217 if (m_haveMax) {
00218 intItem->setMaxValue(m_max);
00219 }
00220
00221 item = intItem;
00222 } else if (m_type == "password") {
00223 item = m_config->addItemPassword(m_name, *d->newString(), m_default, m_key);
00224 } else if (m_type == "path") {
00225 item = m_config->addItemPath(m_name, *d->newString(), m_default, m_key);
00226 } else if (m_type == "string") {
00227 item = m_config->addItemString(m_name, *d->newString(), m_default, m_key);
00228 } else if (m_type == "stringlist") {
00229
00230 item = m_config->addItemStringList(m_name, *d->newStringList(),
00231 m_default.split(','), m_key);
00232 } else if (m_type == "uint") {
00233 KConfigSkeleton::ItemUInt *uintItem =
00234 m_config->addItemUInt(m_name, *d->newUint(), m_default.toUInt(), m_key);
00235 if (m_haveMin) {
00236 uintItem->setMinValue(m_min);
00237 }
00238 if (m_haveMax) {
00239 uintItem->setMaxValue(m_max);
00240 }
00241 item = uintItem;
00242 } else if (m_type == "url") {
00243 m_key = (m_key.isEmpty()) ? m_name : m_key;
00244 KConfigSkeleton::ItemUrl *urlItem =
00245 new KConfigSkeleton::ItemUrl(m_config->currentGroup(),
00246 m_key, *d->newUrl(),
00247 m_default);
00248 m_config->addItem(urlItem, m_name);
00249 item = urlItem;
00250 } else if (m_type == "double") {
00251 KConfigSkeleton::ItemDouble *doubleItem = m_config->addItemDouble(m_name,
00252 *d->newDouble(), m_default.toDouble(), m_key);
00253 if (m_haveMin) {
00254 doubleItem->setMinValue(m_min);
00255 }
00256 if (m_haveMax) {
00257 doubleItem->setMaxValue(m_max);
00258 }
00259 item = doubleItem;
00260 } else if (m_type == "intlist") {
00261 QStringList tmpList = m_default.split(',');
00262 QList<qint32> defaultList;
00263 foreach (const QString &tmp, tmpList) {
00264 defaultList.append(tmp.toInt());
00265 }
00266 item = m_config->addItemIntList(m_name, *d->newIntList(), defaultList, m_key);
00267 } else if (m_type == "longlong") {
00268 KConfigSkeleton::ItemLongLong *longlongItem = m_config->addItemLongLong(m_name,
00269 *d->newLongLong(), m_default.toLongLong(), m_key);
00270 if (m_haveMin) {
00271 longlongItem->setMinValue(m_min);
00272 }
00273 if (m_haveMax) {
00274 longlongItem->setMaxValue(m_max);
00275 }
00276 item = longlongItem;
00277
00278
00279
00280
00281
00282 } else if (m_type == "point") {
00283 QPoint defaultPoint;
00284 QStringList tmpList = m_default.split(',');
00285 while (tmpList.size() >= 2) {
00286 defaultPoint.setX(tmpList[0].toInt());
00287 defaultPoint.setY(tmpList[1].toInt());
00288 }
00289 item = m_config->addItemPoint(m_name, *d->newPoint(), defaultPoint, m_key);
00290 } else if (m_type == "rect") {
00291 QRect defaultRect;
00292 QStringList tmpList = m_default.split(',');
00293 while (tmpList.size() >= 4) {
00294 defaultRect.setCoords(tmpList[0].toInt(), tmpList[1].toInt(),
00295 tmpList[2].toInt(), tmpList[3].toInt());
00296 }
00297 item = m_config->addItemRect(m_name, *d->newRect(), defaultRect, m_key);
00298 } else if (m_type == "size") {
00299 QSize defaultSize;
00300 QStringList tmpList = m_default.split(',');
00301 while (tmpList.size() >= 2) {
00302 defaultSize.setWidth(tmpList[0].toInt());
00303 defaultSize.setHeight(tmpList[1].toInt());
00304 }
00305 item = m_config->addItemSize(m_name, *d->newSize(), defaultSize, m_key);
00306 } else if (m_type == "ulonglong") {
00307 KConfigSkeleton::ItemULongLong *ulonglongItem =
00308 m_config->addItemULongLong(m_name, *d->newULongLong(), m_default.toULongLong(), m_key);
00309 if (m_haveMin) {
00310 ulonglongItem->setMinValue(m_min);
00311 }
00312 if (m_haveMax) {
00313 ulonglongItem->setMaxValue(m_max);
00314 }
00315 item = ulonglongItem;
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 }
00326
00327 if (item) {
00328 item->setLabel(m_label);
00329 item->setWhatsThis(m_whatsThis);
00330 d->keysToNames.insert(item->group() + item->key(), item->name());
00331 }
00332 }
00333
00334 void ConfigLoaderHandler::resetState()
00335 {
00336 m_haveMin = false;
00337 m_min = 0;
00338 m_haveMax = false;
00339 m_max = 0;
00340 m_name.clear();
00341 m_type.clear();
00342 m_label.clear();
00343 m_default.clear();
00344 m_key.clear();
00345 m_whatsThis.clear();
00346 m_enumChoices.clear();
00347 m_inChoice = false;
00348 }
00349
00350 ConfigLoader::ConfigLoader(const QString &configFile, QIODevice *xml, QObject *parent)
00351 : KConfigSkeleton(configFile, parent),
00352 d(new ConfigLoaderPrivate)
00353 {
00354 d->parse(this, xml);
00355 }
00356
00357 ConfigLoader::ConfigLoader(KSharedConfigPtr config, QIODevice *xml, QObject *parent)
00358 : KConfigSkeleton(config, parent),
00359 d(new ConfigLoaderPrivate)
00360 {
00361 d->parse(this, xml);
00362 }
00363
00364
00365
00366
00367 ConfigLoader::ConfigLoader(const KConfigGroup *config, QIODevice *xml, QObject *parent)
00368 : KConfigSkeleton(KSharedConfig::openConfig(config->config()->name()), parent),
00369 d(new ConfigLoaderPrivate)
00370 {
00371 KConfigGroup group = config->parent();
00372 d->baseGroup = config->name();
00373 while (group.isValid() && group.name() != "<default>") {
00374 d->baseGroup = group.name() + '\x1d' + d->baseGroup;
00375 group = group.parent();
00376 }
00377 d->parse(this, xml);
00378 }
00379
00380 ConfigLoader::~ConfigLoader()
00381 {
00382 delete d;
00383 }
00384
00385 KConfigSkeletonItem *ConfigLoader::findItem(const QString &group, const QString &key)
00386 {
00387 return KConfigSkeleton::findItem(d->keysToNames[group + key]);
00388 }
00389
00390 KConfigSkeletonItem *ConfigLoader::findItemByName(const QString &name)
00391 {
00392 return KConfigSkeleton::findItem(name);
00393 }
00394
00395 QVariant ConfigLoader::property(const QString &name)
00396 {
00397 KConfigSkeletonItem *item = KConfigSkeleton::findItem(name);
00398
00399 if (item) {
00400 return item->property();
00401 }
00402
00403 return QVariant();
00404 }
00405
00406 bool ConfigLoader::hasGroup(const QString &group) const
00407 {
00408 return d->groups.contains(group);
00409 }
00410
00411 QStringList ConfigLoader::groupList() const
00412 {
00413 return d->groups;
00414 }
00415
00416 void ConfigLoader::usrWriteConfig()
00417 {
00418 if (d->saveDefaults) {
00419 KConfigSkeletonItem::List itemList = items();
00420 for(int i = 0; i < itemList.size(); i++) {
00421 KConfigGroup cg(config(), itemList.at(i)->group());
00422 cg.writeEntry(itemList.at(i)->key(), "");
00423 }
00424 }
00425 }
00426
00427 }