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