1 /* 2 This file is part of the KDE libraries 3 SPDX-FileCopyrightText: 2006, 2007 Thomas Braxton <kde.braxton@gmail.com> 4 SPDX-FileCopyrightText: 1999-2000 Preston Brown <pbrown@kde.org> 5 SPDX-FileCopyrightText: 1996-2000 Matthias Kalle Dalheimer <kalle@kde.org> 6 7 SPDX-License-Identifier: LGPL-2.0-or-later 8 */ 9 10 #ifndef KCONFIGDATA_P_H 11 #define KCONFIGDATA_P_H 12 13 #include <QByteArray> 14 #include <QDebug> 15 #include <QMap> 16 #include <QString> 17 18 /** 19 * map/dict/list config node entry. 20 * @internal 21 */ 22 struct KEntry { 23 /** Constructor. @internal */ KEntryKEntry24 KEntry() 25 : mValue() 26 , bDirty(false) 27 , bGlobal(false) 28 , bImmutable(false) 29 , bDeleted(false) 30 , bExpand(false) 31 , bReverted(false) 32 , bLocalizedCountry(false) 33 , bNotify(false) 34 , bOverridesGlobal(false) 35 { 36 } 37 /** @internal */ 38 QByteArray mValue; 39 /** 40 * Must the entry be written back to disk? 41 */ 42 bool bDirty : 1; 43 /** 44 * Entry should be written to the global config file 45 */ 46 bool bGlobal : 1; 47 /** 48 * Entry can not be modified. 49 */ 50 bool bImmutable : 1; 51 /** 52 * Entry has been deleted. 53 */ 54 bool bDeleted : 1; 55 /** 56 * Whether to apply dollar expansion or not. 57 */ 58 bool bExpand : 1; 59 /** 60 * Entry has been reverted to its default value (from a more global file). 61 */ 62 bool bReverted : 1; 63 /** 64 * Entry is for a localized key. If @c false the value references just language e.g. "de", 65 * if @c true the value references language and country, e.g. "de_DE". 66 **/ 67 bool bLocalizedCountry : 1; 68 69 bool bNotify : 1; 70 71 /** 72 * Entry will need to be written on a non global file even if it matches default value 73 */ 74 bool bOverridesGlobal : 1; 75 }; 76 77 // These operators are used to check whether an entry which is about 78 // to be written equals the previous value. As such, this intentionally 79 // omits the dirty/notify flag from the comparison. 80 inline bool operator==(const KEntry &k1, const KEntry &k2) 81 { 82 /* clang-format off */ 83 return k1.bGlobal == k2.bGlobal 84 && k1.bImmutable == k2.bImmutable 85 && k1.bDeleted == k2.bDeleted 86 && k1.bExpand == k2.bExpand 87 && k1.mValue == k2.mValue; 88 /* clang-format on */ 89 } 90 91 inline bool operator!=(const KEntry &k1, const KEntry &k2) 92 { 93 return !(k1 == k2); 94 } 95 96 /** 97 * key structure holding both the actual key and the group 98 * to which it belongs. 99 * @internal 100 */ 101 struct KEntryKey { 102 /** Constructor. @internal */ 103 KEntryKey(const QByteArray &_group = QByteArray(), const QByteArray &_key = QByteArray(), bool isLocalized = false, bool isDefault = false) mGroupKEntryKey104 : mGroup(_group) 105 , mKey(_key) 106 , bLocal(isLocalized) 107 , bDefault(isDefault) 108 , bRaw(false) 109 { 110 ; 111 } 112 /** 113 * The "group" to which this EntryKey belongs 114 */ 115 QByteArray mGroup; 116 /** 117 * The _actual_ key of the entry in question 118 */ 119 QByteArray mKey; 120 /** 121 * Entry is localised or not 122 */ 123 bool bLocal : 1; 124 /** 125 * Entry indicates if this is a default value. 126 */ 127 bool bDefault : 1; 128 /** @internal 129 * Key is a raw unprocessed key. 130 * @warning this should only be set during merging, never for normal use. 131 */ 132 bool bRaw : 1; 133 }; 134 135 /** 136 * Compares two KEntryKeys (needed for QMap). The order is localized, localized-default, 137 * non-localized, non-localized-default 138 * @internal 139 */ 140 inline bool operator<(const KEntryKey &k1, const KEntryKey &k2) 141 { 142 int result = k1.mGroup.compare(k2.mGroup); 143 if (result != 0) { 144 return result < 0; 145 } 146 147 result = k1.mKey.compare(k2.mKey); 148 if (result != 0) { 149 return result < 0; 150 } 151 152 if (k1.bLocal != k2.bLocal) { 153 return k1.bLocal; 154 } 155 return (!k1.bDefault && k2.bDefault); 156 } 157 158 QDebug operator<<(QDebug dbg, const KEntryKey &key); 159 QDebug operator<<(QDebug dbg, const KEntry &entry); 160 161 /** 162 * \relates KEntry 163 * type specifying a map of entries (key,value pairs). 164 * The keys are actually a key in a particular config file group together 165 * with the group name. 166 * @internal 167 */ 168 class KEntryMap : public QMap<KEntryKey, KEntry> 169 { 170 public: 171 enum SearchFlag { 172 SearchDefaults = 1, 173 SearchLocalized = 2, 174 }; 175 Q_DECLARE_FLAGS(SearchFlags, SearchFlag) 176 177 enum EntryOption { 178 EntryDirty = 1, 179 EntryGlobal = 2, 180 EntryImmutable = 4, 181 EntryDeleted = 8, 182 EntryExpansion = 16, 183 EntryRawKey = 32, 184 EntryLocalizedCountry = 64, 185 EntryNotify = 128, 186 EntryDefault = (SearchDefaults << 16), 187 EntryLocalized = (SearchLocalized << 16), 188 }; 189 Q_DECLARE_FLAGS(EntryOptions, EntryOption) 190 191 Iterator findExactEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()); 192 193 Iterator findEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()); 194 195 ConstIterator findEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()) const 196 { 197 return constFindEntry(group, key, flags); 198 } 199 200 ConstIterator constFindEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()) const; 201 202 /** 203 * Returns true if the entry gets dirtied or false in other case 204 */ 205 bool setEntry(const QByteArray &group, const QByteArray &key, const QByteArray &value, EntryOptions options); 206 setEntry(const QByteArray & group,const QByteArray & key,const QString & value,EntryOptions options)207 void setEntry(const QByteArray &group, const QByteArray &key, const QString &value, EntryOptions options) 208 { 209 setEntry(group, key, value.toUtf8(), options); 210 } 211 212 QString getEntry(const QByteArray &group, 213 const QByteArray &key, 214 const QString &defaultValue = QString(), 215 SearchFlags flags = SearchFlags(), 216 bool *expand = nullptr) const; 217 218 bool hasEntry(const QByteArray &group, const QByteArray &key = QByteArray(), SearchFlags flags = SearchFlags()) const; 219 220 bool getEntryOption(const ConstIterator &it, EntryOption option) const; getEntryOption(const QByteArray & group,const QByteArray & key,SearchFlags flags,EntryOption option)221 bool getEntryOption(const QByteArray &group, const QByteArray &key, SearchFlags flags, EntryOption option) const 222 { 223 return getEntryOption(findEntry(group, key, flags), option); 224 } 225 226 void setEntryOption(Iterator it, EntryOption option, bool bf); setEntryOption(const QByteArray & group,const QByteArray & key,SearchFlags flags,EntryOption option,bool bf)227 void setEntryOption(const QByteArray &group, const QByteArray &key, SearchFlags flags, EntryOption option, bool bf) 228 { 229 setEntryOption(findEntry(group, key, flags), option, bf); 230 } 231 232 bool revertEntry(const QByteArray &group, const QByteArray &key, EntryOptions options, SearchFlags flags = SearchFlags()); 233 }; 234 Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::SearchFlags) 235 Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::EntryOptions) 236 237 /** 238 * \relates KEntry 239 * type for iterating over keys in a KEntryMap in sorted order. 240 * @internal 241 */ 242 typedef QMap<KEntryKey, KEntry>::Iterator KEntryMapIterator; 243 244 /** 245 * \relates KEntry 246 * type for iterating over keys in a KEntryMap in sorted order. 247 * It is const, thus you cannot change the entries in the iterator, 248 * only examine them. 249 * @internal 250 */ 251 typedef QMap<KEntryKey, KEntry>::ConstIterator KEntryMapConstIterator; 252 253 #endif 254