File indexing completed on 2024-05-12 11:47:18
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2006, 2007 Thomas Braxton <kde.braxton@gmail.com> 0004 SPDX-FileCopyrightText: 1999-2000 Preston Brown <pbrown@kde.org> 0005 SPDX-FileCopyrightText: 1996-2000 Matthias Kalle Dalheimer <kalle@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #ifndef KCONFIGDATA_P_H 0011 #define KCONFIGDATA_P_H 0012 0013 #include <QByteArray> 0014 #include <QDebug> 0015 #include <QMap> 0016 #include <QString> 0017 0018 /** 0019 * map/dict/list config node entry. 0020 * @internal 0021 */ 0022 struct KEntry { 0023 /** Constructor. @internal */ 0024 KEntry() 0025 : mValue() 0026 , bDirty(false) 0027 , bGlobal(false) 0028 , bImmutable(false) 0029 , bDeleted(false) 0030 , bExpand(false) 0031 , bReverted(false) 0032 , bLocalizedCountry(false) 0033 , bNotify(false) 0034 , bOverridesGlobal(false) 0035 { 0036 } 0037 /** @internal */ 0038 QByteArray mValue; 0039 /** 0040 * Must the entry be written back to disk? 0041 */ 0042 bool bDirty : 1; 0043 /** 0044 * Entry should be written to the global config file 0045 */ 0046 bool bGlobal : 1; 0047 /** 0048 * Entry can not be modified. 0049 */ 0050 bool bImmutable : 1; 0051 /** 0052 * Entry has been deleted. 0053 */ 0054 bool bDeleted : 1; 0055 /** 0056 * Whether to apply dollar expansion or not. 0057 */ 0058 bool bExpand : 1; 0059 /** 0060 * Entry has been reverted to its default value (from a more global file). 0061 */ 0062 bool bReverted : 1; 0063 /** 0064 * Entry is for a localized key. If @c false the value references just language e.g. "de", 0065 * if @c true the value references language and country, e.g. "de_DE". 0066 **/ 0067 bool bLocalizedCountry : 1; 0068 0069 bool bNotify : 1; 0070 0071 /** 0072 * Entry will need to be written on a non global file even if it matches default value 0073 */ 0074 bool bOverridesGlobal : 1; 0075 }; 0076 0077 Q_DECLARE_TYPEINFO(KEntry, Q_MOVABLE_TYPE); 0078 0079 // These operators are used to check whether an entry which is about 0080 // to be written equals the previous value. As such, this intentionally 0081 // omits the dirty/notify flag from the comparison. 0082 inline bool operator==(const KEntry &k1, const KEntry &k2) 0083 { 0084 /* clang-format off */ 0085 return k1.bGlobal == k2.bGlobal 0086 && k1.bImmutable == k2.bImmutable 0087 && k1.bDeleted == k2.bDeleted 0088 && k1.bExpand == k2.bExpand 0089 && k1.mValue == k2.mValue; 0090 /* clang-format on */ 0091 } 0092 0093 inline bool operator!=(const KEntry &k1, const KEntry &k2) 0094 { 0095 return !(k1 == k2); 0096 } 0097 0098 /** 0099 * key structure holding both the actual key and the group 0100 * to which it belongs. 0101 * @internal 0102 */ 0103 struct KEntryKey { 0104 /** Constructor. @internal */ 0105 KEntryKey(const QByteArray &_group = QByteArray(), const QByteArray &_key = QByteArray(), bool isLocalized = false, bool isDefault = false) 0106 : mGroup(_group) 0107 , mKey(_key) 0108 , bLocal(isLocalized) 0109 , bDefault(isDefault) 0110 , bRaw(false) 0111 { 0112 ; 0113 } 0114 /** 0115 * The "group" to which this EntryKey belongs 0116 */ 0117 QByteArray mGroup; 0118 /** 0119 * The _actual_ key of the entry in question 0120 */ 0121 QByteArray mKey; 0122 /** 0123 * Entry is localised or not 0124 */ 0125 bool bLocal : 1; 0126 /** 0127 * Entry indicates if this is a default value. 0128 */ 0129 bool bDefault : 1; 0130 /** @internal 0131 * Key is a raw unprocessed key. 0132 * @warning this should only be set during merging, never for normal use. 0133 */ 0134 bool bRaw : 1; 0135 }; 0136 0137 Q_DECLARE_TYPEINFO(KEntryKey, Q_MOVABLE_TYPE); 0138 0139 /** 0140 * Compares two KEntryKeys (needed for QMap). The order is localized, localized-default, 0141 * non-localized, non-localized-default 0142 * @internal 0143 */ 0144 inline bool operator<(const KEntryKey &k1, const KEntryKey &k2) 0145 { 0146 int result = k1.mGroup.compare(k2.mGroup); 0147 if (result != 0) { 0148 return result < 0; 0149 } 0150 0151 result = k1.mKey.compare(k2.mKey); 0152 if (result != 0) { 0153 return result < 0; 0154 } 0155 0156 if (k1.bLocal != k2.bLocal) { 0157 return k1.bLocal; 0158 } 0159 return (!k1.bDefault && k2.bDefault); 0160 } 0161 0162 /** 0163 * Returns the minimum key that has @a mGroup == @p group. 0164 * 0165 * @note The returned "minimum key" is consistent with KEntryKey's operator<(). 0166 * The return value of this function can be passed to KEntryMap::lowerBound(). 0167 */ 0168 inline KEntryKey minimumGroupKey(const QByteArray &group) 0169 { 0170 return KEntryKey(group, QByteArray{}, true, false); 0171 } 0172 0173 QDebug operator<<(QDebug dbg, const KEntryKey &key); 0174 QDebug operator<<(QDebug dbg, const KEntry &entry); 0175 0176 /** 0177 * \relates KEntry 0178 * type specifying a map of entries (key,value pairs). 0179 * The keys are actually a key in a particular config file group together 0180 * with the group name. 0181 * @internal 0182 */ 0183 class KEntryMap : public QMap<KEntryKey, KEntry> 0184 { 0185 public: 0186 enum SearchFlag { 0187 SearchDefaults = 1, 0188 SearchLocalized = 2, 0189 }; 0190 Q_DECLARE_FLAGS(SearchFlags, SearchFlag) 0191 0192 enum EntryOption { 0193 EntryDirty = 1, 0194 EntryGlobal = 2, 0195 EntryImmutable = 4, 0196 EntryDeleted = 8, 0197 EntryExpansion = 16, 0198 EntryRawKey = 32, 0199 EntryLocalizedCountry = 64, 0200 EntryNotify = 128, 0201 EntryDefault = (SearchDefaults << 16), 0202 EntryLocalized = (SearchLocalized << 16), 0203 }; 0204 Q_DECLARE_FLAGS(EntryOptions, EntryOption) 0205 0206 Iterator findExactEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()); 0207 0208 Iterator findEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()); 0209 0210 ConstIterator findEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()) const 0211 { 0212 return constFindEntry(group, key, flags); 0213 } 0214 0215 ConstIterator constFindEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()) const; 0216 0217 /** 0218 * Returns true if the entry gets dirtied or false in other case 0219 */ 0220 bool setEntry(const QByteArray &group, const QByteArray &key, const QByteArray &value, EntryOptions options); 0221 0222 void setEntry(const QByteArray &group, const QByteArray &key, const QString &value, EntryOptions options) 0223 { 0224 setEntry(group, key, value.toUtf8(), options); 0225 } 0226 0227 QString getEntry(const QByteArray &group, 0228 const QByteArray &key, 0229 const QString &defaultValue = QString(), 0230 SearchFlags flags = SearchFlags(), 0231 bool *expand = nullptr) const; 0232 0233 bool hasEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()) const; 0234 0235 bool getEntryOption(const ConstIterator &it, EntryOption option) const; 0236 bool getEntryOption(const QByteArray &group, const QByteArray &key, SearchFlags flags, EntryOption option) const 0237 { 0238 return getEntryOption(findEntry(group, key, flags), option); 0239 } 0240 0241 void setEntryOption(Iterator it, EntryOption option, bool bf); 0242 void setEntryOption(const QByteArray &group, const QByteArray &key, SearchFlags flags, EntryOption option, bool bf) 0243 { 0244 setEntryOption(findEntry(group, key, flags), option, bf); 0245 } 0246 0247 bool revertEntry(const QByteArray &group, const QByteArray &key, EntryOptions options, SearchFlags flags = SearchFlags()); 0248 0249 template<typename ConstIteratorUser> 0250 void forEachEntryWhoseGroupStartsWith(const QByteArray &groupPrefix, ConstIteratorUser callback) const 0251 { 0252 for (auto it = lowerBound(minimumGroupKey(groupPrefix)), end = cend(); it != end && it.key().mGroup.startsWith(groupPrefix); ++it) { 0253 callback(it); 0254 } 0255 } 0256 0257 template<typename ConstIteratorPredicate> 0258 bool anyEntryWhoseGroupStartsWith(const QByteArray &groupPrefix, ConstIteratorPredicate predicate) const 0259 { 0260 for (auto it = lowerBound(minimumGroupKey(groupPrefix)), end = cend(); it != end && it.key().mGroup.startsWith(groupPrefix); ++it) { 0261 if (predicate(it)) { 0262 return true; 0263 } 0264 } 0265 return false; 0266 } 0267 }; 0268 Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::SearchFlags) 0269 Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::EntryOptions) 0270 0271 /** 0272 * \relates KEntry 0273 * type for iterating over keys in a KEntryMap in sorted order. 0274 * @internal 0275 */ 0276 typedef QMap<KEntryKey, KEntry>::Iterator KEntryMapIterator; 0277 0278 /** 0279 * \relates KEntry 0280 * type for iterating over keys in a KEntryMap in sorted order. 0281 * It is const, thus you cannot change the entries in the iterator, 0282 * only examine them. 0283 * @internal 0284 */ 0285 typedef QMap<KEntryKey, KEntry>::ConstIterator KEntryMapConstIterator; 0286 0287 #endif