00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef KCONFIGDATA_H
00024 #define KCONFIGDATA_H
00025
00026 #include <QtCore/QByteArray>
00027 #include <QtCore/QString>
00028 #include <QtCore/QMap>
00029 #include <QtCore/QDebug>
00030
00035 struct KEntry
00036 {
00038 KEntry()
00039 : mValue(), bDirty(false),
00040 bGlobal(false), bImmutable(false), bDeleted(false), bExpand(false) {}
00042 QByteArray mValue;
00046 bool bDirty :1;
00050 bool bGlobal:1;
00054 bool bImmutable:1;
00058 bool bDeleted:1;
00062 bool bExpand:1;
00063 };
00064
00065
00066 inline bool operator ==(const KEntry &k1, const KEntry &k2)
00067 {
00068 int result = qstrcmp(k1.mValue.constData(), k2.mValue.constData());
00069 return (result == 0 && k1.bDirty == k2.bDirty && k1.bGlobal == k2.bGlobal
00070 && k1.bImmutable == k2.bImmutable && k1.bDeleted == k2.bDeleted &&
00071 k1.bExpand == k2.bExpand);
00072 }
00073
00074 inline bool operator !=(const KEntry &k1, const KEntry &k2)
00075 {
00076 return !(k1 == k2);
00077 }
00078
00084 struct KEntryKey
00085 {
00087 KEntryKey(const QByteArray& _group = QByteArray(),
00088 const QByteArray& _key = QByteArray(), bool isLocalized=false, bool isDefault=false)
00089 : mGroup(_group), mKey(_key), bLocal(isLocalized), bDefault(isDefault), bRaw(false)
00090 { ; }
00094 QByteArray mGroup;
00098 QByteArray mKey;
00102 bool bLocal :1;
00106 bool bDefault:1;
00111 bool bRaw:1;
00112 };
00113
00119 inline bool operator <(const KEntryKey &k1, const KEntryKey &k2)
00120 {
00121 int result = qstrcmp(k1.mGroup.constData(), k2.mGroup.constData());
00122 if (result != 0) {
00123 return result < 0;
00124 }
00125
00126 result = qstrcmp(k1.mKey.constData(), k2.mKey.constData());
00127 if (result != 0) {
00128 return result < 0;
00129 }
00130
00131 if (k1.bLocal != k2.bLocal)
00132 return k1.bLocal;
00133 return (!k1.bDefault && k2.bDefault);
00134 }
00135
00143 class KEntryMap : public QMap<KEntryKey, KEntry>
00144 {
00145 public:
00146 enum SearchFlag {
00147 SearchDefaults=1,
00148 SearchLocalized=2
00149 };
00150 Q_DECLARE_FLAGS(SearchFlags, SearchFlag)
00151
00152 enum EntryOption {
00153 EntryDirty=1,
00154 EntryGlobal=2,
00155 EntryImmutable=4,
00156 EntryDeleted=8,
00157 EntryExpansion=16,
00158 EntryRawKey=32,
00159 EntryDefault=(SearchDefaults<<16),
00160 EntryLocalized=(SearchLocalized<<16)
00161 };
00162 Q_DECLARE_FLAGS(EntryOptions, EntryOption)
00163
00164 Iterator findExactEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
00165 SearchFlags flags = SearchFlags())
00166 {
00167 KEntryKey theKey(group, key, false, bool(flags&SearchDefaults));
00168
00169
00170 if (flags&SearchLocalized) {
00171 theKey.bLocal = true;
00172 return find(theKey);
00173 }
00174 return find(theKey);
00175 }
00176
00177 Iterator findEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
00178 SearchFlags flags = SearchFlags())
00179 {
00180 KEntryKey theKey(group, key, false, bool(flags&SearchDefaults));
00181
00182
00183 if (flags&SearchLocalized) {
00184 theKey.bLocal = true;
00185
00186 Iterator it = find(theKey);
00187 if (it != end())
00188 return it;
00189
00190 theKey.bLocal = false;
00191 }
00192 return find(theKey);
00193 }
00194
00195 ConstIterator findEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
00196 SearchFlags flags = SearchFlags()) const
00197 {
00198 KEntryKey theKey(group, key, false, bool(flags&SearchDefaults));
00199
00200
00201 if (flags&SearchLocalized) {
00202 theKey.bLocal = true;
00203
00204 ConstIterator it = find(theKey);
00205 if (it != constEnd())
00206 return it;
00207
00208 theKey.bLocal = false;
00209 }
00210 return find(theKey);
00211 }
00212
00216 bool setEntry(const QByteArray& group, const QByteArray& key,
00217 const QByteArray& value, EntryOptions options)
00218 {
00219 KEntryKey k;
00220 KEntry e;
00221 bool newKey = false;
00222
00223 const Iterator it = findExactEntry(group, key, SearchFlags(options>>16));
00224
00225 if (key.isEmpty()) {
00226 k.mGroup = group;
00227 e.bImmutable = (options&EntryImmutable);
00228 if(it == end())
00229 {
00230 insert(k, e);
00231 return true;
00232 } else if(it.value() == e)
00233 return false;
00234
00235 it.value() = e;
00236 return true;
00237 }
00238
00239
00240 if (it != end()) {
00241 if (it->bImmutable)
00242 return false;
00243 k = it.key();
00244 e = *it;
00245 } else {
00246
00247 KEntryMap const *that = this;
00248 ConstIterator cit = that->findEntry(group);
00249 if (cit == constEnd())
00250 insert(KEntryKey(group), KEntry());
00251 else if (cit->bImmutable)
00252 return false;
00253
00254 k = KEntryKey(group, key);
00255 newKey = true;
00256 }
00257
00258
00259 k.bLocal = (options&EntryLocalized);
00260 k.bDefault = (options&EntryDefault);
00261 k.bRaw = (options&EntryRawKey);
00262
00263
00264
00265
00266 e.mValue = value;
00267 e.bDirty = e.bDirty || (options&EntryDirty);
00268 e.bGlobal = (options&EntryGlobal);
00269
00270
00271 e.bImmutable = e.bImmutable || (options&EntryImmutable);
00272 if (value.isNull())
00273 e.bDeleted = e.bDeleted || (options&EntryDeleted);
00274 else
00275 e.bDeleted = false;
00276 e.bExpand = (options&EntryExpansion);
00277
00278
00279
00280
00281 if(newKey)
00282 {
00283 insert(k, e);
00284 if(k.bDefault)
00285 {
00286 k.bDefault = false;
00287 insert(k, e);
00288 }
00289
00290 return true;
00291 } else {
00292
00293 if(it.value() != e)
00294 {
00295 it.value() = e;
00296 if(k.bDefault)
00297 {
00298 k.bDefault = false;
00299 insert(k, e);
00300 }
00301 if (!(options & EntryLocalized)) {
00302 KEntryKey theKey(group, key, true, false);
00303 remove(theKey);
00304 if (k.bDefault) {
00305 theKey.bDefault = false;
00306 remove(theKey);
00307 }
00308 }
00309 return true;
00310 } else {
00311 if (!(options & EntryLocalized)) {
00312 KEntryKey theKey(group, key, true, false);
00313 bool ret = false;
00314 Iterator cit = find(theKey);
00315 if (cit != end()) {
00316 erase(cit);
00317 ret = true;
00318 }
00319 if (k.bDefault) {
00320 theKey.bDefault = false;
00321 Iterator cit = find(theKey);
00322 if (cit != end()) {
00323 erase(cit);
00324 return true;
00325 }
00326 }
00327 return ret;
00328 }
00329
00330
00331
00332 return false;
00333 }
00334 }
00335 }
00336
00337 void setEntry(const QByteArray& group, const QByteArray& key,
00338 const QString & value, EntryOptions options)
00339 {
00340 setEntry(group, key, value.toUtf8(), options);
00341 }
00342
00343 QString getEntry(const QByteArray& group, const QByteArray& key,
00344 const QString & defaultValue = QString(),
00345 SearchFlags flags = SearchFlags(),
00346 bool * expand=0) const
00347 {
00348 const ConstIterator it = findEntry(group, key, flags);
00349 QString theValue = defaultValue;
00350
00351 if (it != constEnd() && !it->bDeleted) {
00352 if (!it->mValue.isNull()) {
00353 const QByteArray data=it->mValue;
00354 theValue = QString::fromUtf8(data.constData(), data.length());
00355 if (expand)
00356 *expand = it->bExpand;
00357 }
00358 }
00359
00360 return theValue;
00361 }
00362
00363
00364
00365 bool hasEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
00366 SearchFlags flags = SearchFlags()) const
00367 {
00368 const ConstIterator it = findEntry(group, key, flags);
00369 if (it == constEnd())
00370 return false;
00371 if (key.isNull())
00372 return it->mValue.isNull();
00373 return !it->bDeleted;
00374 }
00375
00376 bool getEntryOption(const ConstIterator& it, EntryOption option) const
00377 {
00378 if (it != constEnd()) {
00379 switch (option) {
00380 case EntryDirty:
00381 return it->bDirty;
00382 case EntryLocalized:
00383 return it.key().bLocal;
00384 case EntryGlobal:
00385 return it->bGlobal;
00386 case EntryImmutable:
00387 return it->bImmutable;
00388 case EntryDeleted:
00389 return it->bDeleted;
00390 case EntryExpansion:
00391 return it->bExpand;
00392 default:
00393 break;
00394 }
00395 }
00396
00397 return false;
00398 }
00399 bool getEntryOption(const QByteArray& group, const QByteArray& key,
00400 SearchFlags flags, EntryOption option) const
00401 {
00402 return getEntryOption(findEntry(group, key, flags), option);
00403 }
00404
00405 void setEntryOption(Iterator it, EntryOption option, bool bf)
00406 {
00407 if (it != end()) {
00408 switch (option) {
00409 case EntryDirty:
00410 it->bDirty = bf;
00411 break;
00412 case EntryGlobal:
00413 it->bGlobal = bf;
00414 break;
00415 case EntryImmutable:
00416 it->bImmutable = bf;
00417 break;
00418 case EntryDeleted:
00419 it->bDeleted = bf;
00420 break;
00421 case EntryExpansion:
00422 it->bExpand = bf;
00423 break;
00424 default:
00425 break;
00426 }
00427 }
00428 }
00429 void setEntryOption(const QByteArray& group, const QByteArray& key, SearchFlags flags,
00430 EntryOption option, bool bf)
00431 {
00432 setEntryOption(findEntry(group, key, flags), option, bf);
00433 }
00434
00435 void revertEntry(const QByteArray& group, const QByteArray& key, SearchFlags flags=SearchFlags())
00436 {
00437 Iterator entry = findEntry(group, key, flags);
00438 if (entry != end()) {
00439
00440
00441
00442 const ConstIterator defaultEntry(entry+1);
00443 if (defaultEntry != constEnd() && defaultEntry.key().bDefault) {
00444 *entry = *defaultEntry;
00445 entry->bDirty = true;
00446 } else if (!entry->mValue.isNull()){
00447 entry->mValue = QByteArray();
00448 entry->bDirty = true;
00449 entry->bDeleted = true;
00450 }
00451
00452
00453
00454 }
00455 }
00456 };
00457 Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::SearchFlags)
00458 Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::EntryOptions)
00459
00465 typedef QMap<KEntryKey, KEntry>::Iterator KEntryMapIterator;
00466
00474 typedef QMap<KEntryKey, KEntry>::ConstIterator KEntryMapConstIterator;
00475
00476 #endif