• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • config
kconfig.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDE libraries
3 Copyright (c) 2006, 2007 Thomas Braxton <kde.braxton@gmail.com>
4 Copyright (c) 1999 Preston Brown <pbrown@kde.org>
5 Copyright (c) 1997-1999 Matthias Kalle Dalheimer <kalle@kde.org>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include "kconfig.h"
24#include "kconfig_p.h"
25
26#include <cstdlib>
27#include <fcntl.h>
28#include <unistd.h>
29
30#include "kconfigbackend.h"
31#include "kconfiggroup.h"
32#include <kde_file.h>
33#include <kstringhandler.h>
34#include <klocale.h>
35#include <kstandarddirs.h>
36#include <kurl.h>
37#include <kcomponentdata.h>
38#include <ktoolinvocation.h>
39#include <kaboutdata.h>
40#include <kdebug.h>
41
42#include <qbytearray.h>
43#include <qfile.h>
44#include <qdir.h>
45#include <qdatetime.h>
46#include <qrect.h>
47#include <qsize.h>
48#include <qcolor.h>
49#include <QtCore/QProcess>
50#include <QtCore/QPointer>
51#include <QtCore/QSet>
52#include <QtCore/QStack>
53
54bool KConfigPrivate::mappingsRegistered=false;
55
56KConfigPrivate::KConfigPrivate(const KComponentData &componentData_, KConfig::OpenFlags flags,
57 const char* resource)
58 : openFlags(flags), resourceType(resource), mBackend(0),
59 bDynamicBackend(true), bDirty(false), bReadDefaults(false),
60 bFileImmutable(false), bForceGlobal(false), bSuppressGlobal(false),
61 componentData(componentData_), configState(KConfigBase::NoAccess)
62{
63 sGlobalFileName = componentData.dirs()->saveLocation("config", QString(), false) + QLatin1String("kdeglobals");
64
65 static int use_etc_kderc = -1;
66 if (use_etc_kderc < 0)
67 use_etc_kderc = getenv("KDE_SKIP_KDERC") != 0 ? 0 : 1; // for unit tests
68 if (use_etc_kderc) {
69
70 etc_kderc =
71#ifdef Q_WS_WIN
72 QFile::decodeName( qgetenv("WINDIR") + "/kde4rc" );
73#else
74 QLatin1String("/etc/kde4rc");
75#endif
76 if (!KStandardDirs::checkAccess(etc_kderc, R_OK)) {
77 etc_kderc.clear();
78 }
79 }
80
81// if (!mappingsRegistered) {
82// KEntryMap tmp;
83// if (!etc_kderc.isEmpty()) {
84// KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, etc_kderc, QLatin1String("INI"));
85// backend->parseConfig( "en_US", tmp, KConfigBackend::ParseDefaults);
86// }
87// const QString kde4rc(QDir::home().filePath(".kde4rc"));
88// if (KStandardDirs::checkAccess(kde4rc, R_OK)) {
89// KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, kde4rc, QLatin1String("INI"));
90// backend->parseConfig( "en_US", tmp, KConfigBackend::ParseOptions());
91// }
92// KConfigBackend::registerMappings(tmp);
93// mappingsRegistered = true;
94// }
95
96 setLocale(KGlobal::hasLocale() ? KGlobal::locale()->language() : KLocale::defaultLanguage());
97}
98
99
100bool KConfigPrivate::lockLocal()
101{
102 if (mBackend) {
103 return mBackend->lock(componentData);
104 }
105 // anonymous object - pretend we locked it
106 return true;
107}
108
109void KConfigPrivate::copyGroup(const QByteArray& source, const QByteArray& destination,
110 KConfigGroup *otherGroup, KConfigBase::WriteConfigFlags flags) const
111{
112 KEntryMap& otherMap = otherGroup->config()->d_ptr->entryMap;
113 const int len = source.length();
114 const bool sameName = (destination == source);
115
116 // we keep this bool outside the foreach loop so that if
117 // the group is empty, we don't end up marking the other config
118 // as dirty erroneously
119 bool dirtied = false;
120
121 for (KEntryMap::ConstIterator entryMapIt( entryMap.constBegin() ); entryMapIt != entryMap.constEnd(); ++entryMapIt) {
122 const QByteArray& group = entryMapIt.key().mGroup;
123
124 if (!group.startsWith(source)) // nothing to do
125 continue;
126
127 // don't copy groups that start with the same prefix, but are not sub-groups
128 if (group.length() > len && group[len] != '\x1d')
129 continue;
130
131 KEntryKey newKey = entryMapIt.key();
132
133 if (flags & KConfigBase::Localized) {
134 newKey.bLocal = true;
135 }
136
137 if (!sameName)
138 newKey.mGroup.replace(0, len, destination);
139
140 KEntry entry = entryMap[ entryMapIt.key() ];
141 dirtied = entry.bDirty = flags & KConfigBase::Persistent;
142
143 if (flags & KConfigBase::Global) {
144 entry.bGlobal = true;
145 }
146
147 otherMap[newKey] = entry;
148 }
149
150 if (dirtied) {
151 otherGroup->config()->d_ptr->bDirty = true;
152 }
153}
154
155QString KConfigPrivate::expandString(const QString& value)
156{
157 QString aValue = value;
158
159 // check for environment variables and make necessary translations
160 int nDollarPos = aValue.indexOf( QLatin1Char('$') );
161 while( nDollarPos != -1 && nDollarPos+1 < aValue.length()) {
162 // there is at least one $
163 if( aValue[nDollarPos+1] != QLatin1Char('$') ) {
164 int nEndPos = nDollarPos+1;
165 // the next character is not $
166 QString aVarName;
167 if ( aValue[nEndPos] == QLatin1Char('{') ) {
168 while ( (nEndPos <= aValue.length()) && (aValue[nEndPos] != QLatin1Char('}')) )
169 nEndPos++;
170 nEndPos++;
171 aVarName = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 );
172 } else {
173 while ( nEndPos <= aValue.length() &&
174 (aValue[nEndPos].isNumber() ||
175 aValue[nEndPos].isLetter() ||
176 aValue[nEndPos] == QLatin1Char('_') ) )
177 nEndPos++;
178 aVarName = aValue.mid( nDollarPos+1, nEndPos-nDollarPos-1 );
179 }
180 QString env;
181 if (!aVarName.isEmpty()) {
182#ifdef Q_OS_WIN
183 if (aVarName == QLatin1String("HOME"))
184 env = QDir::homePath();
185 else
186#endif
187 {
188 QByteArray pEnv = qgetenv( aVarName.toLatin1() );
189 if( !pEnv.isEmpty() )
190 // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!!
191 // An environment variable may contain values in 8bit
192 // locale specified encoding or UTF8 encoding
193 env = KStringHandler::from8Bit( pEnv );
194 }
195 aValue.replace(nDollarPos, nEndPos-nDollarPos, env);
196 nDollarPos += env.length();
197 } else
198 aValue.remove( nDollarPos, nEndPos-nDollarPos );
199 } else {
200 // remove one of the dollar signs
201 aValue.remove( nDollarPos, 1 );
202 nDollarPos++;
203 }
204 nDollarPos = aValue.indexOf( QLatin1Char('$'), nDollarPos );
205 }
206
207 return aValue;
208}
209
210
211KConfig::KConfig( const QString& file, OpenFlags mode,
212 const char* resourceType)
213 : d_ptr(new KConfigPrivate(KGlobal::mainComponent(), mode, resourceType))
214{
215 d_ptr->changeFileName(file, resourceType); // set the local file name
216
217 // read initial information off disk
218 reparseConfiguration();
219}
220
221KConfig::KConfig( const KComponentData& componentData, const QString& file, OpenFlags mode,
222 const char* resourceType)
223 : d_ptr(new KConfigPrivate(componentData, mode, resourceType))
224{
225 d_ptr->changeFileName(file, resourceType); // set the local file name
226
227 // read initial information off disk
228 reparseConfiguration();
229}
230
231KConfig::KConfig(const QString& file, const QString& backend, const char* resourceType)
232 : d_ptr(new KConfigPrivate(KGlobal::mainComponent(), SimpleConfig, resourceType))
233{
234 d_ptr->mBackend = KConfigBackend::create(d_ptr->componentData, file, backend);
235 d_ptr->bDynamicBackend = false;
236 d_ptr->changeFileName(file, ""); // set the local file name
237
238 // read initial information off disk
239 reparseConfiguration();
240}
241
242KConfig::KConfig(KConfigPrivate &d)
243 : d_ptr(&d)
244{
245}
246
247KConfig::~KConfig()
248{
249 Q_D(KConfig);
250 if (d->bDirty && d->mBackend.isUnique())
251 sync();
252 delete d;
253}
254
255const KComponentData& KConfig::componentData() const
256{
257 Q_D(const KConfig);
258 return d->componentData;
259}
260
261QStringList KConfig::groupList() const
262{
263 Q_D(const KConfig);
264 QSet<QString> groups;
265
266 for (KEntryMap::ConstIterator entryMapIt( d->entryMap.constBegin() ); entryMapIt != d->entryMap.constEnd(); ++entryMapIt) {
267 const KEntryKey& key = entryMapIt.key();
268 const QByteArray group = key.mGroup;
269 if (key.mKey.isNull() && !group.isEmpty() && group != "<default>" && group != "$Version") {
270 const QString groupname = QString::fromUtf8(group);
271 groups << groupname.left(groupname.indexOf(QLatin1Char('\x1d')));
272 }
273 }
274
275 return groups.toList();
276}
277
278QStringList KConfigPrivate::groupList(const QByteArray& group) const
279{
280 QByteArray theGroup = group + '\x1d';
281 QSet<QString> groups;
282
283 for (KEntryMap::ConstIterator entryMapIt( entryMap.constBegin() ); entryMapIt != entryMap.constEnd(); ++entryMapIt) {
284 const KEntryKey& key = entryMapIt.key();
285 if (key.mKey.isNull() && key.mGroup.startsWith(theGroup)) {
286 const QString groupname = QString::fromUtf8(key.mGroup.mid(theGroup.length()));
287 groups << groupname.left(groupname.indexOf(QLatin1Char('\x1d')));
288 }
289 }
290
291 return groups.toList();
292}
293
294static bool isGroupOrSubGroupMatch(const QByteArray& potentialGroup, const QByteArray& group)
295{
296 if (!potentialGroup.startsWith(group)) {
297 return false;
298 }
299 return potentialGroup.length() == group.length() || potentialGroup[group.length()] == '\x1d';
300}
301
302// List all sub groups, including subsubgroups
303QSet<QByteArray> KConfigPrivate::allSubGroups(const QByteArray& parentGroup) const
304{
305 QSet<QByteArray> groups;
306
307 for (KEntryMap::const_iterator entryMapIt = entryMap.begin(); entryMapIt != entryMap.end(); ++entryMapIt) {
308 const KEntryKey& key = entryMapIt.key();
309 if (key.mKey.isNull() && isGroupOrSubGroupMatch(key.mGroup, parentGroup)) {
310 groups << key.mGroup;
311 }
312 }
313 return groups;
314}
315
316bool KConfigPrivate::hasNonDeletedEntries(const QByteArray& group) const
317{
318 for (KEntryMap::const_iterator it = entryMap.begin(); it != entryMap.end(); ++it) {
319 const KEntryKey& key = it.key();
320 // Check for any non-deleted entry
321 if (isGroupOrSubGroupMatch(key.mGroup, group) && !key.mKey.isNull() && !it->bDeleted)
322 return true;
323 }
324 return false;
325}
326
327
328QStringList KConfigPrivate::keyListImpl(const QByteArray& theGroup) const
329{
330 QStringList keys;
331
332 const KEntryMapConstIterator theEnd = entryMap.constEnd();
333 KEntryMapConstIterator it = entryMap.findEntry(theGroup);
334 if (it != theEnd) {
335 ++it; // advance past the special group entry marker
336
337 QSet<QString> tmp;
338 for (; it != theEnd && it.key().mGroup == theGroup; ++it) {
339 const KEntryKey& key = it.key();
340 if (!key.mKey.isNull() && !it->bDeleted)
341 tmp << QString::fromUtf8(key.mKey);
342 }
343 keys = tmp.toList();
344 }
345
346 return keys;
347}
348
349QStringList KConfig::keyList(const QString& aGroup) const
350{
351 Q_D(const KConfig);
352 const QByteArray theGroup(aGroup.isEmpty() ? "<default>" : aGroup.toUtf8());
353 return d->keyListImpl(theGroup);
354}
355
356QMap<QString,QString> KConfig::entryMap(const QString& aGroup) const
357{
358 Q_D(const KConfig);
359 QMap<QString, QString> theMap;
360 const QByteArray theGroup(aGroup.isEmpty() ? "<default>" : aGroup.toUtf8());
361
362 const KEntryMapConstIterator theEnd = d->entryMap.constEnd();
363 KEntryMapConstIterator it = d->entryMap.findEntry(theGroup, 0, 0);
364 if (it != theEnd) {
365 ++it; // advance past the special group entry marker
366
367 for (; it != theEnd && it.key().mGroup == theGroup; ++it) {
368 // leave the default values and deleted entries out
369 if (!it->bDeleted && !it.key().bDefault) {
370 const QString key = QString::fromUtf8(it.key().mKey.constData());
371 // the localized entry should come first, so don't overwrite it
372 // with the non-localized entry
373 if (!theMap.contains(key)) {
374 if (it->bExpand) {
375 theMap.insert(key,KConfigPrivate::expandString(QString::fromUtf8(it->mValue.constData())));
376 } else {
377 theMap.insert(key,QString::fromUtf8(it->mValue.constData()));
378 }
379 }
380 }
381 }
382 }
383
384 return theMap;
385}
386
387// TODO KDE5: return a bool value
388void KConfig::sync()
389{
390 Q_D(KConfig);
391
392 if (isImmutable() || name().isEmpty()) {
393 // can't write to an immutable or anonymous file.
394 return;
395 }
396
397 if (d->bDirty && d->mBackend) {
398 const QByteArray utf8Locale(locale().toUtf8());
399
400 // Create the containing dir, maybe it wasn't there
401 d->mBackend->createEnclosing();
402
403 // lock the local file
404 if (d->configState == ReadWrite && !d->lockLocal()) {
405 qWarning() << "couldn't lock local file";
406 return;
407 }
408
409 // Rewrite global/local config only if there is a dirty entry in it.
410 bool writeGlobals = false;
411 bool writeLocals = false;
412 foreach (const KEntry& e, d->entryMap) {
413 if (e.bDirty) {
414 if (e.bGlobal) {
415 writeGlobals = true;
416 } else {
417 writeLocals = true;
418 }
419
420 if (writeGlobals && writeLocals) {
421 break;
422 }
423 }
424 }
425
426 d->bDirty = false; // will revert to true if a config write fails
427
428 if (d->wantGlobals() && writeGlobals) {
429 KSharedPtr<KConfigBackend> tmp = KConfigBackend::create(componentData(), d->sGlobalFileName);
430 if (d->configState == ReadWrite && !tmp->lock(componentData())) {
431 qWarning() << "couldn't lock global file";
432 d->bDirty = true;
433 return;
434 }
435 if (!tmp->writeConfig(utf8Locale, d->entryMap, KConfigBackend::WriteGlobal, d->componentData)) {
436 d->bDirty = true;
437 // TODO KDE5: return false? (to tell the app that writing wasn't possible, e.g.
438 // config file is immutable or disk full)
439 }
440 if (tmp->isLocked()) {
441 tmp->unlock();
442 }
443 }
444
445 if (writeLocals) {
446 if (!d->mBackend->writeConfig(utf8Locale, d->entryMap, KConfigBackend::WriteOptions(), d->componentData)) {
447 d->bDirty = true;
448 // TODO KDE5: return false? (to tell the app that writing wasn't possible, e.g.
449 // config file is immutable or disk full)
450 }
451 }
452 if (d->mBackend->isLocked()) {
453 d->mBackend->unlock();
454 }
455 }
456}
457
458void KConfig::markAsClean()
459{
460 Q_D(KConfig);
461 d->bDirty = false;
462
463 // clear any dirty flags that entries might have set
464 const KEntryMapIterator theEnd = d->entryMap.end();
465 for (KEntryMapIterator it = d->entryMap.begin(); it != theEnd; ++it)
466 it->bDirty = false;
467}
468
469bool KConfig::isDirty() const
470{
471 Q_D(const KConfig);
472 return d->bDirty;
473}
474
475void KConfig::checkUpdate(const QString &id, const QString &updateFile)
476{
477 const KConfigGroup cg(this, "$Version");
478 const QString cfg_id = updateFile+QLatin1Char(':')+id;
479 const QStringList ids = cg.readEntry("update_info", QStringList());
480 if (!ids.contains(cfg_id)) {
481 KToolInvocation::kdeinitExecWait(QString::fromLatin1("kconf_update"), QStringList() << QString::fromLatin1("--check") << updateFile);
482 reparseConfiguration();
483 }
484}
485
486KConfig* KConfig::copyTo(const QString &file, KConfig *config) const
487{
488 Q_D(const KConfig);
489 if (!config)
490 config = new KConfig(componentData(), QString(), SimpleConfig);
491 config->d_func()->changeFileName(file, d->resourceType);
492 config->d_func()->entryMap = d->entryMap;
493 config->d_func()->bFileImmutable = false;
494
495 const KEntryMapIterator theEnd = config->d_func()->entryMap.end();
496 for (KEntryMapIterator it = config->d_func()->entryMap.begin(); it != theEnd; ++it)
497 it->bDirty = true;
498 config->d_ptr->bDirty = true;
499
500 return config;
501}
502
503QString KConfig::name() const
504{
505 Q_D(const KConfig);
506 return d->fileName;
507}
508
509void KConfigPrivate::changeFileName(const QString& name, const char* type)
510{
511 fileName = name;
512
513 QString file;
514 if (name.isEmpty()) {
515 if (wantDefaults()) { // accessing default app-specific config "appnamerc"
516 const QString appName = componentData.aboutData()->appName();
517 if (!appName.isEmpty()) {
518 fileName = appName + QLatin1String("rc");
519 if (type && *type)
520 resourceType = type; // only change it if it's not empty
521 file = KStandardDirs::locateLocal(resourceType, fileName, false, componentData);
522 }
523 } else if (wantGlobals()) { // accessing "kdeglobals" - XXX used anywhere?
524 resourceType = "config";
525 fileName = QLatin1String("kdeglobals");
526 file = sGlobalFileName;
527 } // else anonymous config.
528 // KDE5: remove these magic overloads
529 } else if (QDir::isAbsolutePath(fileName)) {
530 fileName = KStandardDirs::realFilePath(fileName);
531 file = fileName;
532 } else {
533 if (type && *type)
534 resourceType = type; // only change it if it's not empty
535 file = KStandardDirs::locateLocal(resourceType, fileName, false, componentData);
536 }
537
538 if (file.isEmpty()) {
539 openFlags = KConfig::SimpleConfig;
540 return;
541 }
542
543#ifndef Q_OS_WIN
544 bSuppressGlobal = (file == sGlobalFileName);
545#else
546 bSuppressGlobal = (file.compare(sGlobalFileName, Qt::CaseInsensitive) == 0);
547#endif
548
549 if (bDynamicBackend || !mBackend) // allow dynamic changing of backend
550 mBackend = KConfigBackend::create(componentData, file);
551 else
552 mBackend->setFilePath(file);
553
554 configState = mBackend->accessMode();
555}
556
557void KConfig::reparseConfiguration()
558{
559 Q_D(KConfig);
560 if (d->fileName.isEmpty()) {
561 return;
562 }
563
564 // Don't lose pending changes
565 if (!d->isReadOnly() && d->bDirty)
566 sync();
567
568 d->entryMap.clear();
569
570 d->bFileImmutable = false;
571
572 // Parse all desired files from the least to the most specific.
573 if (d->wantGlobals())
574 d->parseGlobalFiles();
575
576 d->parseConfigFiles();
577}
578
579
580QStringList KConfigPrivate::getGlobalFiles() const
581{
582 const KStandardDirs *const dirs = componentData.dirs();
583 QStringList globalFiles;
584 foreach (const QString& dir1, dirs->findAllResources("config", QLatin1String("kdeglobals")))
585 globalFiles.push_front(dir1);
586 foreach (const QString& dir2, dirs->findAllResources("config", QLatin1String("system.kdeglobals")))
587 globalFiles.push_front(dir2);
588 if (!etc_kderc.isEmpty())
589 globalFiles.push_front(etc_kderc);
590 return globalFiles;
591}
592
593void KConfigPrivate::parseGlobalFiles()
594{
595 const QStringList globalFiles = getGlobalFiles();
596// qDebug() << "parsing global files" << globalFiles;
597
598 // TODO: can we cache the values in etc_kderc / other global files
599 // on a per-application basis?
600 const QByteArray utf8Locale = locale.toUtf8();
601 foreach(const QString& file, globalFiles) {
602 KConfigBackend::ParseOptions parseOpts = KConfigBackend::ParseGlobal|KConfigBackend::ParseExpansions;
603#ifndef Q_OS_WIN
604 if (file != sGlobalFileName)
605#else
606 if (file.compare(sGlobalFileName, Qt::CaseInsensitive) != 0)
607#endif
608 parseOpts |= KConfigBackend::ParseDefaults;
609
610 KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, file);
611 if ( backend->parseConfig( utf8Locale, entryMap, parseOpts) == KConfigBackend::ParseImmutable)
612 break;
613 }
614}
615
616void KConfigPrivate::parseConfigFiles()
617{
618 // can only read the file if there is a backend and a file name
619 if (mBackend && !fileName.isEmpty()) {
620
621 bFileImmutable = false;
622
623 QList<QString> files;
624 if (wantDefaults()) {
625 if (bSuppressGlobal) {
626 files = getGlobalFiles();
627 } else {
628 foreach (const QString& f, componentData.dirs()->findAllResources(
629 resourceType, fileName))
630 files.prepend(f);
631 }
632 } else {
633 files << mBackend->filePath();
634 }
635 if (!isSimple())
636 files = extraFiles.toList() + files;
637
638// qDebug() << "parsing local files" << files;
639
640 const QByteArray utf8Locale = locale.toUtf8();
641 foreach(const QString& file, files) {
642#ifndef Q_OS_WIN
643 if (file == mBackend->filePath()) {
644#else
645 if (file.compare(mBackend->filePath(), Qt::CaseInsensitive) == 0) {
646#endif
647 switch (mBackend->parseConfig(utf8Locale, entryMap, KConfigBackend::ParseExpansions)) {
648 case KConfigBackend::ParseOk:
649 break;
650 case KConfigBackend::ParseImmutable:
651 bFileImmutable = true;
652 break;
653 case KConfigBackend::ParseOpenError:
654 configState = KConfigBase::NoAccess;
655 break;
656 }
657 } else {
658 KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, file);
659 bFileImmutable = (backend->parseConfig(utf8Locale, entryMap,
660 KConfigBackend::ParseDefaults|KConfigBackend::ParseExpansions)
661 == KConfigBackend::ParseImmutable);
662 }
663
664 if (bFileImmutable)
665 break;
666 }
667 if (componentData.dirs()->isRestrictedResource(resourceType, fileName))
668 bFileImmutable = true;
669 }
670}
671
672KConfig::AccessMode KConfig::accessMode() const
673{
674 Q_D(const KConfig);
675 return d->configState;
676}
677
678void KConfig::addConfigSources(const QStringList& files)
679{
680 Q_D(KConfig);
681 foreach(const QString& file, files) {
682 d->extraFiles.push(file);
683 }
684
685 if (!files.isEmpty()) {
686 reparseConfiguration();
687 }
688}
689
690QString KConfig::locale() const
691{
692 Q_D(const KConfig);
693 return d->locale;
694}
695
696bool KConfigPrivate::setLocale(const QString& aLocale)
697{
698 if (aLocale != locale) {
699 locale = aLocale;
700 return true;
701 }
702 return false;
703}
704
705bool KConfig::setLocale(const QString& locale)
706{
707 Q_D(KConfig);
708 if (d->setLocale(locale)) {
709 reparseConfiguration();
710 return true;
711 }
712 return false;
713}
714
715void KConfig::setReadDefaults(bool b)
716{
717 Q_D(KConfig);
718 d->bReadDefaults = b;
719}
720
721bool KConfig::readDefaults() const
722{
723 Q_D(const KConfig);
724 return d->bReadDefaults;
725}
726
727bool KConfig::isImmutable() const
728{
729 Q_D(const KConfig);
730 return d->bFileImmutable;
731}
732
733bool KConfig::isGroupImmutableImpl(const QByteArray& aGroup) const
734{
735 Q_D(const KConfig);
736 return isImmutable() || d->entryMap.getEntryOption(aGroup, 0, 0, KEntryMap::EntryImmutable);
737}
738
739#ifndef KDE_NO_DEPRECATED
740void KConfig::setForceGlobal(bool b)
741{
742 Q_D(KConfig);
743 d->bForceGlobal = b;
744}
745#endif
746
747#ifndef KDE_NO_DEPRECATED
748bool KConfig::forceGlobal() const
749{
750 Q_D(const KConfig);
751 return d->bForceGlobal;
752}
753#endif
754
755KConfigGroup KConfig::groupImpl(const QByteArray &group)
756{
757 return KConfigGroup(this, group.constData());
758}
759
760const KConfigGroup KConfig::groupImpl(const QByteArray &group) const
761{
762 return KConfigGroup(this, group.constData());
763}
764
765KEntryMap::EntryOptions convertToOptions(KConfig::WriteConfigFlags flags)
766{
767 KEntryMap::EntryOptions options=0;
768
769 if (flags&KConfig::Persistent)
770 options |= KEntryMap::EntryDirty;
771 if (flags&KConfig::Global)
772 options |= KEntryMap::EntryGlobal;
773 if (flags&KConfig::Localized)
774 options |= KEntryMap::EntryLocalized;
775 return options;
776}
777
778void KConfig::deleteGroupImpl(const QByteArray &aGroup, WriteConfigFlags flags)
779{
780 Q_D(KConfig);
781 KEntryMap::EntryOptions options = convertToOptions(flags)|KEntryMap::EntryDeleted;
782
783 const QSet<QByteArray> groups = d->allSubGroups(aGroup);
784 foreach (const QByteArray& group, groups) {
785 const QStringList keys = d->keyListImpl(group);
786 foreach (const QString& _key, keys) {
787 const QByteArray &key = _key.toUtf8();
788 if (d->canWriteEntry(group, key.constData())) {
789 d->entryMap.setEntry(group, key, QByteArray(), options);
790 d->bDirty = true;
791 }
792 }
793 }
794}
795
796bool KConfig::isConfigWritable(bool warnUser)
797{
798 Q_D(KConfig);
799 bool allWritable = (d->mBackend.isNull()? false: d->mBackend->isWritable());
800
801 if (warnUser && !allWritable) {
802 QString errorMsg;
803 if (!d->mBackend.isNull()) // TODO how can be it be null? Set errorMsg appropriately
804 errorMsg = d->mBackend->nonWritableErrorMessage();
805
806 // Note: We don't ask the user if we should not ask this question again because we can't save the answer.
807 errorMsg += i18n("Please contact your system administrator.");
808 QString cmdToExec = KStandardDirs::findExe(QString::fromLatin1("kdialog"));
809 if (!cmdToExec.isEmpty() && componentData().isValid())
810 {
811 QProcess::execute(cmdToExec, QStringList()
812 << QString::fromLatin1("--title") << componentData().componentName()
813 << QString::fromLatin1("--msgbox") << errorMsg);
814 }
815 }
816
817 d->configState = allWritable ? ReadWrite : ReadOnly; // update the read/write status
818
819 return allWritable;
820}
821
822bool KConfig::hasGroupImpl(const QByteArray& aGroup) const
823{
824 Q_D(const KConfig);
825
826 // No need to look for the actual group entry anymore, or for subgroups:
827 // a group exists if it contains any non-deleted entry.
828
829 return d->hasNonDeletedEntries(aGroup);
830}
831
832bool KConfigPrivate::canWriteEntry(const QByteArray& group, const char* key, bool isDefault) const
833{
834 if (bFileImmutable ||
835 entryMap.getEntryOption(group, key, KEntryMap::SearchLocalized, KEntryMap::EntryImmutable))
836 return isDefault;
837 return true;
838}
839
840void KConfigPrivate::putData( const QByteArray& group, const char* key,
841 const QByteArray& value, KConfigBase::WriteConfigFlags flags, bool expand)
842{
843 KEntryMap::EntryOptions options = convertToOptions(flags);
844
845 if (bForceGlobal)
846 options |= KEntryMap::EntryGlobal;
847 if (expand)
848 options |= KEntryMap::EntryExpansion;
849
850 if (value.isNull()) // deleting entry
851 options |= KEntryMap::EntryDeleted;
852
853 bool dirtied = entryMap.setEntry(group, key, value, options);
854 if (dirtied && (flags & KConfigBase::Persistent))
855 bDirty = true;
856}
857
858void KConfigPrivate::revertEntry(const QByteArray& group, const char* key)
859{
860 bool dirtied = entryMap.revertEntry(group, key);
861 if (dirtied)
862 bDirty = true;
863}
864
865QByteArray KConfigPrivate::lookupData(const QByteArray& group, const char* key,
866 KEntryMap::SearchFlags flags) const
867{
868 if (bReadDefaults)
869 flags |= KEntryMap::SearchDefaults;
870 const KEntryMapConstIterator it = entryMap.findEntry(group, key, flags);
871 if (it == entryMap.constEnd())
872 return QByteArray();
873 return it->mValue;
874}
875
876QString KConfigPrivate::lookupData(const QByteArray& group, const char* key,
877 KEntryMap::SearchFlags flags, bool *expand) const
878{
879 if (bReadDefaults)
880 flags |= KEntryMap::SearchDefaults;
881 return entryMap.getEntry(group, key, QString(), flags, expand);
882}
883
884void KConfig::virtual_hook(int /*id*/, void* /*data*/)
885{
886 /* nothing */
887}
888
KAboutData::appName
QString appName() const
Returns the application's internal name.
Definition: kaboutdata.cpp:678
KComponentData
Per component data.
Definition: kcomponentdata.h:47
KComponentData::dirs
KStandardDirs * dirs() const
Returns the application standard dirs object.
Definition: kcomponentdata.cpp:193
KComponentData::aboutData
const KAboutData * aboutData() const
Returns the about data of this component.
Definition: kcomponentdata.cpp:215
KConfigBackend::create
static KSharedPtr< KConfigBackend > create(const KComponentData &componentData, const QString &fileName=QString(), const QString &system=QString())
Creates a new KConfig backend.
Definition: kconfigbackend.cpp:64
KConfigBackend::WriteGlobal
@ WriteGlobal
Definition: kconfigbackend.h:103
KConfigBackend::filePath
QString filePath() const
Definition: kconfigbackend.cpp:123
KConfigBackend::lock
virtual bool lock(const KComponentData &componentData)=0
Lock the file.
KConfigBackend::ParseExpansions
@ ParseExpansions
entries should be marked as default
Definition: kconfigbackend.h:96
KConfigBackend::ParseGlobal
@ ParseGlobal
Definition: kconfigbackend.h:94
KConfigBackend::ParseDefaults
@ ParseDefaults
entries should be marked as global
Definition: kconfigbackend.h:95
KConfigBackend::ParseOpenError
@ ParseOpenError
the configuration is immutable
Definition: kconfigbackend.h:112
KConfigBackend::ParseOk
@ ParseOk
Definition: kconfigbackend.h:110
KConfigBackend::ParseImmutable
@ ParseImmutable
the configuration was opened read/write
Definition: kconfigbackend.h:111
KConfigBackend::accessMode
virtual KConfigBase::AccessMode accessMode() const =0
KConfigBackend::parseConfig
virtual ParseInfo parseConfig(const QByteArray &locale, KEntryMap &pWriteBackMap, ParseOptions options=ParseOptions())=0
Read persistent storage.
KConfigBackend::setFilePath
virtual void setFilePath(const QString &path)=0
Set the file path.
KConfigBase
Definition: kconfigbase.h:39
KConfigBase::Persistent
@ Persistent
Save this entry when saving the config object.
Definition: kconfigbase.h:46
KConfigBase::Global
@ Global
Save the entry to the global KDE config file instead of the application specific config file.
Definition: kconfigbase.h:50
KConfigBase::Localized
@ Localized
Add the locale tag to the key when writing it.
Definition: kconfigbase.h:55
KConfigBase::AccessMode
AccessMode
Possible return values for accessMode().
Definition: kconfigbase.h:133
KConfigBase::NoAccess
@ NoAccess
Definition: kconfigbase.h:133
KConfigBase::ReadWrite
@ ReadWrite
Definition: kconfigbase.h:133
KConfigBase::group
KConfigGroup group(const QByteArray &group)
Returns an object for the named subgroup.
Definition: kconfigbase.cpp:44
KConfigGroup
A class for one specific group in a KConfig object.
Definition: kconfiggroup.h:54
KConfigGroup::readEntry
T readEntry(const QString &key, const T &aDefault) const
Reads the value of an entry specified by pKey in the current group.
Definition: kconfiggroup.h:248
KConfigGroup::config
KConfig * config()
Return the config object that this group belongs to.
Definition: kconfiggroup.cpp:610
KConfigPrivate
Definition: kconfig_p.h:43
KConfigPrivate::KConfigPrivate
KConfigPrivate(const KComponentData &componentData_, KConfig::OpenFlags flags, const char *resource)
Definition: kconfig.cpp:56
KConfigPrivate::allSubGroups
QSet< QByteArray > allSubGroups(const QByteArray &parentGroup) const
Definition: kconfig.cpp:303
KConfigPrivate::revertEntry
void revertEntry(const QByteArray &group, const char *key)
Definition: kconfig.cpp:858
KConfigPrivate::resourceType
const char * resourceType
Definition: kconfig_p.h:47
KConfigPrivate::copyGroup
void copyGroup(const QByteArray &source, const QByteArray &destination, KConfigGroup *otherGroup, KConfigBase::WriteConfigFlags flags) const
Definition: kconfig.cpp:109
KConfigPrivate::hasNonDeletedEntries
bool hasNonDeletedEntries(const QByteArray &group) const
Definition: kconfig.cpp:316
KConfigPrivate::expandString
static QString expandString(const QString &value)
Definition: kconfig.cpp:155
KConfigPrivate::groupList
QStringList groupList(const QByteArray &group) const
Definition: kconfig.cpp:278
KConfigPrivate::lookupData
QString lookupData(const QByteArray &group, const char *key, KEntryMap::SearchFlags flags, bool *expand) const
Definition: kconfig.cpp:876
KConfigPrivate::canWriteEntry
bool canWriteEntry(const QByteArray &group, const char *key, bool isDefault=false) const
Definition: kconfig.cpp:832
KConfigPrivate::changeFileName
void changeFileName(const QString &fileName, const char *resourceType)
Definition: kconfig.cpp:509
KConfigPrivate::putData
void putData(const QByteArray &group, const char *key, const QByteArray &value, KConfigBase::WriteConfigFlags flags, bool expand=false)
Definition: kconfig.cpp:840
KConfigPrivate::keyListImpl
QStringList keyListImpl(const QByteArray &theGroup) const
Definition: kconfig.cpp:328
KConfigPrivate::bDynamicBackend
bool bDynamicBackend
Definition: kconfig_p.h:81
KConfigPrivate::openFlags
KConfig::OpenFlags openFlags
Definition: kconfig_p.h:46
KConfigPrivate::mBackend
KSharedPtr< KConfigBackend > mBackend
Definition: kconfig_p.h:72
KConfig
The central class of the KDE configuration data system.
Definition: kconfig.h:71
KConfig::copyTo
KConfig * copyTo(const QString &file, KConfig *config=0) const
Copies all entries from this config object to a new config object that will save itself to file.
Definition: kconfig.cpp:486
KConfig::isImmutable
bool isImmutable() const
Definition: kconfig.cpp:727
KConfig::accessMode
AccessMode accessMode() const
Definition: kconfig.cpp:672
KConfig::hasGroupImpl
virtual bool hasGroupImpl(const QByteArray &group) const
Definition: kconfig.cpp:822
KConfig::locale
QString locale() const
locales
Definition: kconfig.cpp:690
KConfig::reparseConfiguration
void reparseConfiguration()
Updates the state of this object to match the persistent storage.
Definition: kconfig.cpp:557
KConfig::entryMap
QMap< QString, QString > entryMap(const QString &aGroup=QString()) const
Returns a map (tree) of entries in a particular group.
Definition: kconfig.cpp:356
KConfig::setReadDefaults
void setReadDefaults(bool b)
defaults
Definition: kconfig.cpp:715
KConfig::forceGlobal
bool forceGlobal() const
Definition: kconfig.cpp:748
KConfig::name
QString name() const
Returns the filename used to store the configuration.
Definition: kconfig.cpp:503
KConfig::readDefaults
bool readDefaults() const
Definition: kconfig.cpp:721
KConfig::isGroupImmutableImpl
virtual bool isGroupImmutableImpl(const QByteArray &aGroup) const
Definition: kconfig.cpp:733
KConfig::checkUpdate
void checkUpdate(const QString &id, const QString &updateFile)
Ensures that the configuration file contains a certain update.
Definition: kconfig.cpp:475
KConfig::~KConfig
virtual ~KConfig()
Definition: kconfig.cpp:247
KConfig::sync
void sync()
Definition: kconfig.cpp:388
KConfig::componentData
const KComponentData & componentData() const
Returns the component data this configuration is for.
Definition: kconfig.cpp:255
KConfig::KConfig
KConfig(const QString &file=QString(), OpenFlags mode=FullConfig, const char *resourceType="config")
Creates a KConfig object to manipulate a configuration file for the current application.
Definition: kconfig.cpp:211
KConfig::virtual_hook
virtual void virtual_hook(int id, void *data)
Virtual hook, used to add new "virtual" functions while maintaining binary compatibility.
Definition: kconfig.cpp:884
KConfig::markAsClean
void markAsClean()
Definition: kconfig.cpp:458
KConfig::addConfigSources
void addConfigSources(const QStringList &sources)
extra config files
Definition: kconfig.cpp:678
KConfig::deleteGroupImpl
virtual void deleteGroupImpl(const QByteArray &group, WriteConfigFlags flags=Normal)
Definition: kconfig.cpp:778
KConfig::isConfigWritable
bool isConfigWritable(bool warnUser)
Whether the configuration can be written to.
Definition: kconfig.cpp:796
KConfig::SimpleConfig
@ SimpleConfig
Just a single config file.
Definition: kconfig.h:96
KConfig::setForceGlobal
void setForceGlobal(bool force)
global
Definition: kconfig.cpp:740
KConfig::isDirty
bool isDirty() const
Returns true if sync has any changes to write out.
Definition: kconfig.cpp:469
KConfig::groupList
QStringList groupList() const
Definition: kconfig.cpp:261
KConfig::groupImpl
virtual KConfigGroup groupImpl(const QByteArray &b)
Definition: kconfig.cpp:755
KConfig::setLocale
bool setLocale(const QString &aLocale)
Sets the locale to aLocale.
Definition: kconfig.cpp:705
KConfig::d_ptr
KConfigPrivate *const d_ptr
Definition: kconfig.h:403
KEntryMap
type specifying a map of entries (key,value pairs).
Definition: kconfigdata.h:153
KEntryMap::getEntry
QString getEntry(const QByteArray &group, const QByteArray &key, const QString &defaultValue=QString(), SearchFlags flags=SearchFlags(), bool *expand=0) const
Definition: kconfigdata.cpp:209
KEntryMap::revertEntry
bool revertEntry(const QByteArray &group, const QByteArray &key, SearchFlags flags=SearchFlags())
Definition: kconfigdata.cpp:289
KEntryMap::findEntry
Iterator findEntry(const QByteArray &group, const QByteArray &key=QByteArray(), SearchFlags flags=SearchFlags())
KEntryMap::getEntryOption
bool getEntryOption(const ConstIterator &it, EntryOption option) const
KEntryMap::EntryImmutable
@ EntryImmutable
Definition: kconfigdata.h:164
KEntryMap::EntryDirty
@ EntryDirty
Definition: kconfigdata.h:162
KEntryMap::EntryLocalized
@ EntryLocalized
Definition: kconfigdata.h:169
KEntryMap::EntryExpansion
@ EntryExpansion
Definition: kconfigdata.h:166
KEntryMap::EntryGlobal
@ EntryGlobal
Definition: kconfigdata.h:163
KEntryMap::EntryDeleted
@ EntryDeleted
Definition: kconfigdata.h:165
KEntryMap::SearchLocalized
@ SearchLocalized
Definition: kconfigdata.h:157
KEntryMap::SearchDefaults
@ SearchDefaults
Definition: kconfigdata.h:156
KEntryMap::setEntry
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.
KLocale::defaultLanguage
static QString defaultLanguage()
Returns the name of the internal language.
Definition: klocale.cpp:615
KSharedPtr
Can be used to control the lifetime of an object that has derived QSharedData.
Definition: ksharedptr.h:64
KStandardDirs
Site-independent access to standard KDE directories.
Definition: kstandarddirs.h:172
KStandardDirs::findExe
static QString findExe(const QString &appname, const QString &pathstr=QString(), SearchOptions options=NoSearchOptions)
Finds the executable in the system path.
Definition: kstandarddirs.cpp:1334
KStandardDirs::checkAccess
static bool checkAccess(const QString &pathname, int mode)
Check, if a file may be accessed in a given mode.
Definition: kstandarddirs.cpp:2120
KStandardDirs::saveLocation
QString saveLocation(const char *type, const QString &suffix=QString(), bool create=true) const
Finds a location to save files into for the given type in the user's home directory.
Definition: kstandarddirs.cpp:1484
KStandardDirs::findAllResources
QStringList findAllResources(const char *type, const QString &filter=QString(), SearchOptions options=NoSearchOptions) const
Tries to find all resources with the specified type.
Definition: kstandarddirs.cpp:900
KStandardDirs::locateLocal
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
This function is much like locate.
Definition: kstandarddirs.cpp:2097
KStandardDirs::realFilePath
static QString realFilePath(const QString &filename)
Expands all symbolic links and resolves references to '/.
Definition: kstandarddirs.cpp:973
KStandardDirs::isRestrictedResource
bool isRestrictedResource(const char *type, const QString &relPath=QString()) const
Checks whether a resource is restricted as part of the KIOSK framework.
Definition: kstandarddirs.cpp:254
KToolInvocation::kdeinitExecWait
static int kdeinitExecWait(const QString &name, const QStringList &args=QStringList(), QString *error=0, int *pid=0, const QByteArray &startup_id=QByteArray())
Starts a program via kdeinit and wait for it to finish.
Definition: ktoolinvocation.cpp:240
QList
Definition: kaboutdata.h:33
QMap
QSet
Definition: k3resolver.h:41
QStringList
QString
kaboutdata.h
kcomponentdata.h
convertToOptions
KEntryMap::EntryOptions convertToOptions(KConfig::WriteConfigFlags flags)
Definition: kconfig.cpp:765
isGroupOrSubGroupMatch
static bool isGroupOrSubGroupMatch(const QByteArray &potentialGroup, const QByteArray &group)
Definition: kconfig.cpp:294
kconfig.h
kconfig_p.h
kconfigbackend.h
kconfiggroup.h
kdebug.h
klocale.h
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
kstandarddirs.h
kstringhandler.h
ktoolinvocation.h
kurl.h
KGlobal
Access to the KDE global objects.
Definition: kglobal.h:334
KGlobal::locale
KLocale * locale()
Returns the global locale object.
Definition: kglobal.cpp:170
KGlobal::hasLocale
bool hasLocale()
Definition: kglobal.cpp:205
KStringHandler::from8Bit
QString from8Bit(const char *str)
Construct QString from a c string, guessing whether it is UTF8- or Local8Bit-encoded.
Definition: kstringhandler.cpp:289
KEntryKey
key structure holding both the actual key and the group to which it belongs.
Definition: kconfigdata.h:90
KEntryKey::mKey
QByteArray mKey
The actual key of the entry in question.
Definition: kconfigdata.h:103
KEntryKey::mGroup
QByteArray mGroup
The "group" to which this EntryKey belongs.
Definition: kconfigdata.h:99
KEntryKey::bLocal
bool bLocal
Entry is localised or not.
Definition: kconfigdata.h:107
KEntry
map/dict/list config node entry.
Definition: kconfigdata.h:36
KEntry::bGlobal
bool bGlobal
Entry should be written to the global config file.
Definition: kconfigdata.h:50
KEntry::bDirty
bool bDirty
Must the entry be written back to disk?
Definition: kconfigdata.h:46
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal