KConfig

kconfigdata.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2006, 2007 Thomas Braxton <[email protected]>
4  SPDX-FileCopyrightText: 1999-2000 Preston Brown <[email protected]>
5  SPDX-FileCopyrightText: 1996-2000 Matthias Kalle Dalheimer <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #include <kconfigdata.h>
11 
12 QDebug operator<<(QDebug dbg, const KEntryKey &key)
13 {
14  dbg.nospace() << "[" << key.mGroup << ", " << key.mKey << (key.bLocal ? " localized" : "") <<
15  (key.bDefault ? " default" : "") << (key.bRaw ? " raw" : "") << "]";
16  return dbg.space();
17 }
18 
19 QDebug operator<<(QDebug dbg, const KEntry &entry)
20 {
21  dbg.nospace() << "[" << entry.mValue << (entry.bDirty ? " dirty" : "") <<
22  (entry.bGlobal ? " global" : "") << (entry.bImmutable ? " immutable" : "") <<
23  (entry.bDeleted ? " deleted" : "") << (entry.bReverted ? " reverted" : "") <<
24  (entry.bExpand ? " expand" : "") << "]";
25 
26  return dbg.space();
27 }
28 
29 QMap< KEntryKey, KEntry >::Iterator KEntryMap::findExactEntry(const QByteArray &group, const QByteArray &key, KEntryMap::SearchFlags flags)
30 {
31  KEntryKey theKey(group, key, bool(flags & SearchLocalized), bool(flags & SearchDefaults));
32  return find(theKey);
33 }
34 
35 QMap< KEntryKey, KEntry >::Iterator KEntryMap::findEntry(const QByteArray &group, const QByteArray &key, KEntryMap::SearchFlags flags)
36 {
37  KEntryKey theKey(group, key, false, bool(flags & SearchDefaults));
38 
39  // try the localized key first
40  if (flags & SearchLocalized) {
41  theKey.bLocal = true;
42 
43  Iterator it = find(theKey);
44  if (it != end()) {
45  return it;
46  }
47 
48  theKey.bLocal = false;
49  }
50  return find(theKey);
51 }
52 
53 QMap< KEntryKey, KEntry >::ConstIterator KEntryMap::findEntry(const QByteArray &group, const QByteArray &key, KEntryMap::SearchFlags flags) const
54 {
55  KEntryKey theKey(group, key, false, bool(flags & SearchDefaults));
56 
57  // try the localized key first
58  if (flags & SearchLocalized) {
59  theKey.bLocal = true;
60 
61  ConstIterator it = find(theKey);
62  if (it != constEnd()) {
63  return it;
64  }
65 
66  theKey.bLocal = false;
67  }
68  return find(theKey);
69 }
70 
71 bool KEntryMap::setEntry(const QByteArray &group, const QByteArray &key, const QByteArray &value, KEntryMap::EntryOptions options)
72 {
73  KEntryKey k;
74  KEntry e;
75  bool newKey = false;
76 
77  const Iterator it = findExactEntry(group, key, SearchFlags(options >> 16));
78 
79  if (key.isEmpty()) { // inserting a group marker
80  k.mGroup = group;
81  e.bImmutable = (options & EntryImmutable);
82  if (options & EntryDeleted) {
83  qWarning("Internal KConfig error: cannot mark groups as deleted");
84  }
85  if (it == end()) {
86  insert(k, e);
87  return true;
88  } else if (it.value() == e) {
89  return false;
90  }
91 
92  it.value() = e;
93  return true;
94  }
95 
96  if (it != end()) {
97  if (it->bImmutable) {
98  return false; // we cannot change this entry. Inherits group immutability.
99  }
100  k = it.key();
101  e = *it;
102  //qDebug() << "found existing entry for key" << k;
103  // If overridden entry is global and not default. And it's overridden by a non global
104  if (e.bGlobal && !(options & EntryGlobal) && !k.bDefault) {
105  e.bOverridesGlobal = true;
106  }
107  } else {
108  // make sure the group marker is in the map
109  KEntryMap const *that = this;
110  ConstIterator cit = that->findEntry(group);
111  if (cit == constEnd()) {
112  insert(KEntryKey(group), KEntry());
113  } else if (cit->bImmutable) {
114  return false; // this group is immutable, so we cannot change this entry.
115  }
116 
117  k = KEntryKey(group, key);
118  newKey = true;
119  }
120 
121  // set these here, since we may be changing the type of key from the one we found
122  k.bLocal = (options & EntryLocalized);
123  k.bDefault = (options & EntryDefault);
124  k.bRaw = (options & EntryRawKey);
125 
126  e.mValue = value;
127  e.bDirty = e.bDirty || (options & EntryDirty);
128  e.bNotify = e.bNotify || (options & EntryNotify);
129 
130  e.bGlobal = (options & EntryGlobal); //we can't use || here, because changes to entries in
131  //kdeglobals would be written to kdeglobals instead
132  //of the local config file, regardless of the globals flag
133  e.bImmutable = e.bImmutable || (options & EntryImmutable);
134  if (value.isNull()) {
135  e.bDeleted = e.bDeleted || (options & EntryDeleted);
136  } else {
137  e.bDeleted = false; // setting a value to a previously deleted entry
138  }
139  e.bExpand = (options & EntryExpansion);
140  e.bReverted = false;
141  if (options & EntryLocalized) {
142  e.bLocalizedCountry = (options & EntryLocalizedCountry);
143  } else {
144  e.bLocalizedCountry = false;
145  }
146 
147  if (newKey) {
148  //qDebug() << "inserting" << k << "=" << value;
149  insert(k, e);
150  if (k.bDefault) {
151  k.bDefault = false;
152  //qDebug() << "also inserting" << k << "=" << value;
153  insert(k, e);
154  }
155  // TODO check for presence of unlocalized key
156  return true;
157  } else {
158 // KEntry e2 = it.value();
159  if (options & EntryLocalized) {
160  // fast exit checks for cases where the existing entry is more specific
161  const KEntry &e2 = it.value();
162  if (e2.bLocalizedCountry && !e.bLocalizedCountry) {
163  // lang_COUNTRY > lang
164  return false;
165  }
166  }
167  if (it.value() != e) {
168  //qDebug() << "changing" << k << "from" << e.mValue << "to" << value;
169  it.value() = e;
170  if (k.bDefault) {
171  KEntryKey nonDefaultKey(k);
172  nonDefaultKey.bDefault = false;
173  insert(nonDefaultKey, e);
174  }
175  if (!(options & EntryLocalized)) {
176  KEntryKey theKey(group, key, true, false);
177  //qDebug() << "non-localized entry, remove localized one:" << theKey;
178  remove(theKey);
179  if (k.bDefault) {
180  theKey.bDefault = true;
181  remove(theKey);
182  }
183  }
184  return true;
185  } else {
186  //qDebug() << k << "was already set to" << e.mValue;
187  if (!(options & EntryLocalized)) {
188  //qDebug() << "unchanged non-localized entry, remove localized one.";
189  KEntryKey theKey(group, key, true, false);
190  bool ret = false;
191  Iterator cit = find(theKey);
192  if (cit != end()) {
193  erase(cit);
194  ret = true;
195  }
196  if (k.bDefault) {
197  theKey.bDefault = true;
198  Iterator cit = find(theKey);
199  if (cit != end()) {
200  erase(cit);
201  return true;
202  }
203  }
204  return ret;
205  }
206  //qDebug() << "localized entry, unchanged, return false";
207  // When we are writing a default, we know that the non-
208  // default is the same as the default, so we can simply
209  // use the same branch.
210  return false;
211  }
212  }
213 }
214 
215 QString KEntryMap::getEntry(const QByteArray &group, const QByteArray &key, const QString &defaultValue, KEntryMap::SearchFlags flags, bool *expand) const
216 {
217  const ConstIterator it = findEntry(group, key, flags);
218  QString theValue = defaultValue;
219 
220  if (it != constEnd() && !it->bDeleted) {
221  if (!it->mValue.isNull()) {
222  const QByteArray data = it->mValue;
223  theValue = QString::fromUtf8(data.constData(), data.length());
224  if (expand) {
225  *expand = it->bExpand;
226  }
227  }
228  }
229 
230  return theValue;
231 }
232 
233 bool KEntryMap::hasEntry(const QByteArray &group, const QByteArray &key, KEntryMap::SearchFlags flags) const
234 {
235  const ConstIterator it = findEntry(group, key, flags);
236  if (it == constEnd()) {
237  return false;
238  }
239  if (it->bDeleted) {
240  return false;
241  }
242  if (key.isNull()) { // looking for group marker
243  return it->mValue.isNull();
244  }
245  // if it->bReverted, we'll just return true; the real answer depends on lookup up with SearchDefaults, though.
246  return true;
247 }
248 
249 bool KEntryMap::getEntryOption(const QMap< KEntryKey, KEntry >::ConstIterator &it, KEntryMap::EntryOption option) const
250 {
251  if (it != constEnd()) {
252  switch (option) {
253  case EntryDirty:
254  return it->bDirty;
255  case EntryLocalized:
256  return it.key().bLocal;
257  case EntryGlobal:
258  return it->bGlobal;
259  case EntryImmutable:
260  return it->bImmutable;
261  case EntryDeleted:
262  return it->bDeleted;
263  case EntryExpansion:
264  return it->bExpand;
265  case EntryNotify:
266  return it->bNotify;
267  default:
268  break; // fall through
269  }
270  }
271 
272  return false;
273 }
274 
275 void KEntryMap::setEntryOption(QMap< KEntryKey, KEntry >::Iterator it, KEntryMap::EntryOption option, bool bf)
276 {
277  if (it != end()) {
278  switch (option) {
279  case EntryDirty:
280  it->bDirty = bf;
281  break;
282  case EntryGlobal:
283  it->bGlobal = bf;
284  break;
285  case EntryImmutable:
286  it->bImmutable = bf;
287  break;
288  case EntryDeleted:
289  it->bDeleted = bf;
290  break;
291  case EntryExpansion:
292  it->bExpand = bf;
293  break;
294  case EntryNotify:
295  it->bNotify = bf;
296  break;
297  default:
298  break; // fall through
299  }
300  }
301 }
302 
303 bool KEntryMap::revertEntry(const QByteArray &group, const QByteArray &key, KEntryMap::EntryOptions options, KEntryMap::SearchFlags flags)
304 {
305  Q_ASSERT((flags & KEntryMap::SearchDefaults) == 0);
306  Iterator entry = findEntry(group, key, flags);
307  if (entry != end()) {
308  //qDebug() << "reverting" << entry.key() << " = " << entry->mValue;
309  if (entry->bReverted) { // already done before
310  return false;
311  }
312 
313  KEntryKey defaultKey(entry.key());
314  defaultKey.bDefault = true;
315  //qDebug() << "looking up default entry with key=" << defaultKey;
316  const ConstIterator defaultEntry = constFind(defaultKey);
317  if (defaultEntry != constEnd()) {
318  Q_ASSERT(defaultEntry.key().bDefault);
319  //qDebug() << "found, update entry";
320  *entry = *defaultEntry; // copy default value, for subsequent lookups
321  } else {
322  entry->mValue = QByteArray();
323  }
324  entry->bNotify = entry->bNotify || (options & EntryNotify);
325  entry->bDirty = true;
326  entry->bReverted = true; // skip it when writing out to disk
327 
328  //qDebug() << "Here's what we have now:" << *this;
329  return true;
330  }
331  return false;
332 }
QMap::iterator erase(QMap::iterator pos)
bool bOverridesGlobal
Entry will need to be written on a non global file even if it matches default value.
Definition: kconfigdata.h:65
bool bDeleted
Entry has been deleted.
Definition: kconfigdata.h:45
map/dict/list config node entry.
Definition: kconfigdata.h:22
bool bReverted
Entry has been reverted to its default value (from a more global file).
Definition: kconfigdata.h:53
bool bDefault
Entry indicates if this is a default value.
Definition: kconfigdata.h:111
bool isNull() const const
bool isEmpty() const const
QDebug & nospace()
QMap::const_iterator constFind(const Key &key) const const
int length() const const
bool bImmutable
Entry can not be modified.
Definition: kconfigdata.h:41
QString fromUtf8(const char *str, int size)
key structure holding both the actual key and the group to which it belongs.
Definition: kconfigdata.h:88
QByteArray mGroup
The "group" to which this EntryKey belongs.
Definition: kconfigdata.h:99
QMap::const_iterator constEnd() const const
const char * constData() const const
bool bLocal
Entry is localised or not.
Definition: kconfigdata.h:107
QMap::iterator end()
QDebug & space()
bool setEntry(const QByteArray &group, const QByteArray &key, const QByteArray &value, EntryOptions options)
Returns true if the entry gets dirtied or false in other case.
Definition: kconfigdata.cpp:71
const Key key(const T &value, const Key &defaultKey) const const
bool bGlobal
Entry should be written to the global config file.
Definition: kconfigdata.h:37
QDataStream & operator<<(QDataStream &out, const KDateTime::Spec &spec)
QByteArray mValue
Definition: kconfigdata.h:29
QByteArray mKey
The actual key of the entry in question.
Definition: kconfigdata.h:103
QMap::iterator insert(const Key &key, const T &value)
bool bLocalizedCountry
Entry is for a localized key.
Definition: kconfigdata.h:58
bool bExpand
Whether to apply dollar expansion or not.
Definition: kconfigdata.h:49
QMap::iterator find(const Key &key)
bool bDirty
Must the entry be written back to disk?
Definition: kconfigdata.h:33
const T value(const Key &key, const T &defaultValue) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jul 3 2020 22:47:12 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.