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
00034 struct KEntry
00035 {
00037 KEntry()
00038 : mValue(), bDirty(false),
00039 bGlobal(false), bImmutable(false), bDeleted(false), bExpand(false) {}
00041 QByteArray mValue;
00045 bool bDirty :1;
00049 bool bGlobal:1;
00053 bool bImmutable:1;
00057 bool bDeleted:1;
00061 bool bExpand:1;
00062 };
00063
00069 struct KEntryKey
00070 {
00072 KEntryKey(const QByteArray& _group = QByteArray(),
00073 const QByteArray& _key = QByteArray(), bool isLocalized=false, bool isDefault=false)
00074 : mGroup(_group), mKey(_key), bLocal(isLocalized), bDefault(isDefault), bRaw(false)
00075 { ; }
00079 QByteArray mGroup;
00083 QByteArray mKey;
00087 bool bLocal :1;
00091 bool bDefault:1;
00096 bool bRaw:1;
00097 };
00098
00104 inline bool operator <(const KEntryKey &k1, const KEntryKey &k2)
00105 {
00106 int result = qstrcmp(k1.mGroup.constData(), k2.mGroup.constData());
00107 if (result != 0) {
00108 return result < 0;
00109 }
00110
00111 result = qstrcmp(k1.mKey.constData(), k2.mKey.constData());
00112 if (result != 0) {
00113 return result < 0;
00114 }
00115
00116 if (k1.bLocal != k2.bLocal)
00117 return k1.bLocal;
00118 return (!k1.bDefault && k2.bDefault);
00119 }
00120
00128 class KEntryMap : public QMap<KEntryKey, KEntry>
00129 {
00130 public:
00131 enum SearchFlag {
00132 SearchDefaults=1,
00133 SearchLocalized=2
00134 };
00135 Q_DECLARE_FLAGS(SearchFlags, SearchFlag)
00136
00137 enum EntryOption {
00138 EntryDirty=1,
00139 EntryGlobal=2,
00140 EntryImmutable=4,
00141 EntryDeleted=8,
00142 EntryExpansion=16,
00143 EntryRawKey=32,
00144 EntryDefault=(SearchDefaults<<16),
00145 EntryLocalized=(SearchLocalized<<16)
00146 };
00147 Q_DECLARE_FLAGS(EntryOptions, EntryOption)
00148
00149 Iterator findEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
00150 SearchFlags flags = SearchFlags())
00151 {
00152 KEntryKey theKey(group, key, false, bool(flags&SearchDefaults));
00153
00154
00155 if (flags&SearchLocalized) {
00156 theKey.bLocal = true;
00157
00158 Iterator it = find(theKey);
00159 if (it != end())
00160 return it;
00161
00162 theKey.bLocal = false;
00163 }
00164 return find(theKey);
00165 }
00166
00167 ConstIterator findEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
00168 SearchFlags flags = SearchFlags()) const
00169 {
00170 KEntryKey theKey(group, key, false, bool(flags&SearchDefaults));
00171
00172
00173 if (flags&SearchLocalized) {
00174 theKey.bLocal = true;
00175
00176 ConstIterator it = find(theKey);
00177 if (it != constEnd())
00178 return it;
00179
00180 theKey.bLocal = false;
00181 }
00182 return find(theKey);
00183 }
00184
00185 void setEntry(const QByteArray& group, const QByteArray& key,
00186 const QByteArray& value, EntryOptions options)
00187 {
00188 KEntryKey k;
00189 KEntry e;
00190
00191 if (key.isEmpty()) {
00192 k.mGroup = group;
00193 e.bImmutable = (options&EntryImmutable);
00194 insert(k, e);
00195 return;
00196 }
00197
00198 const ConstIterator it = findEntry(group, key, SearchFlags(options>>16));
00199
00200 if (it != constEnd()) {
00201 if (it->bImmutable)
00202 return;
00203 k = it.key();
00204 e = *it;
00205 } else {
00206
00207 ConstIterator it = findEntry(group);
00208 if (it == constEnd())
00209 insert(KEntryKey(group), KEntry());
00210 else if (it->bImmutable)
00211 return;
00212
00213 k = KEntryKey(group, key);
00214 }
00215
00216
00217 k.bLocal = (options&EntryLocalized);
00218 k.bDefault = (options&EntryDefault);
00219 k.bRaw = (options&EntryRawKey);
00220
00221
00222
00223
00224 e.mValue = value;
00225 e.bDirty = e.bDirty || (options&EntryDirty);
00226 e.bGlobal = (options&EntryGlobal);
00227
00228
00229 e.bImmutable = e.bImmutable || (options&EntryImmutable);
00230 if (value.isNull())
00231 e.bDeleted = e.bDeleted || (options&EntryDeleted);
00232 else
00233 e.bDeleted = false;
00234 e.bExpand = (options&EntryExpansion);
00235
00236 insert(k, e);
00237
00238
00239
00240
00241 if (k.bDefault) {
00242 k.bDefault = false;
00243 insert(k, e);
00244 }
00245 }
00246 void setEntry(const QByteArray& group, const QByteArray& key,
00247 const QString & value, EntryOptions options)
00248 {
00249 setEntry(group, key, value.toUtf8(), options);
00250 }
00251
00252 QString getEntry(const QByteArray& group, const QByteArray& key,
00253 const QString & defaultValue = QString(),
00254 SearchFlags flags = SearchFlags(),
00255 bool * expand=0) const
00256 {
00257 const ConstIterator it = findEntry(group, key, flags);
00258 QString theValue = defaultValue;
00259
00260 if (it != constEnd() && !it->bDeleted) {
00261 if (!it->mValue.isNull()) {
00262 const QByteArray data=it->mValue;
00263 theValue = QString::fromUtf8(data.constData(), data.length());
00264 if (expand)
00265 *expand = it->bExpand;
00266 }
00267 }
00268
00269 return theValue;
00270 }
00271
00272 bool hasEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
00273 SearchFlags flags = SearchFlags()) const
00274 {
00275 const ConstIterator it = findEntry(group, key, flags);
00276 if (it == constEnd())
00277 return false;
00278 if (key.isNull())
00279 return it->mValue.isNull();
00280 return !it->bDeleted;
00281 }
00282
00283 bool getEntryOption(const ConstIterator& it, EntryOption option) const
00284 {
00285 if (it != constEnd()) {
00286 switch (option) {
00287 case EntryDirty:
00288 return it->bDirty;
00289 case EntryLocalized:
00290 return it.key().bLocal;
00291 case EntryGlobal:
00292 return it->bGlobal;
00293 case EntryImmutable:
00294 return it->bImmutable;
00295 case EntryDeleted:
00296 return it->bDeleted;
00297 case EntryExpansion:
00298 return it->bExpand;
00299 default:
00300 break;
00301 }
00302 }
00303
00304 return false;
00305 }
00306 bool getEntryOption(const QByteArray& group, const QByteArray& key,
00307 SearchFlags flags, EntryOption option) const
00308 {
00309 return getEntryOption(findEntry(group, key, flags), option);
00310 }
00311
00312 void setEntryOption(Iterator it, EntryOption option, bool bf)
00313 {
00314 if (it != constEnd()) {
00315 switch (option) {
00316 case EntryDirty:
00317 it->bDirty = bf;
00318 break;
00319 case EntryGlobal:
00320 it->bGlobal = bf;
00321 break;
00322 case EntryImmutable:
00323 it->bImmutable = bf;
00324 break;
00325 case EntryDeleted:
00326 it->bDeleted = bf;
00327 break;
00328 case EntryExpansion:
00329 it->bExpand = bf;
00330 break;
00331 default:
00332 break;
00333 }
00334 }
00335 }
00336 void setEntryOption(const QByteArray& group, const QByteArray& key, SearchFlags flags,
00337 EntryOption option, bool bf)
00338 {
00339 setEntryOption(findEntry(group, key, flags), option, bf);
00340 }
00341
00342 void revertEntry(const QByteArray& group, const QByteArray& key, SearchFlags flags=SearchFlags())
00343 {
00344 Iterator entry = findEntry(group, key, flags);
00345 if (entry != constEnd()) {
00346
00347
00348
00349 const ConstIterator defaultEntry(entry+1);
00350 if (defaultEntry != constEnd() && defaultEntry.key().bDefault) {
00351 *entry = *defaultEntry;
00352 entry->bDirty = true;
00353 } else if (!entry->mValue.isNull()){
00354 entry->mValue = QByteArray();
00355 entry->bDirty = true;
00356 entry->bDeleted = true;
00357 }
00358
00359
00360
00361 }
00362 }
00363 };
00364 Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::SearchFlags)
00365 Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::EntryOptions)
00366
00372 typedef QMap<KEntryKey, KEntry>::Iterator KEntryMapIterator;
00373
00381 typedef QMap<KEntryKey, KEntry>::ConstIterator KEntryMapConstIterator;
00382
00383 #endif