• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDECore

kconfig.cpp

Go to the documentation of this file.
00001 /*
00002    This file is part of the KDE libraries
00003    Copyright (c) 2006, 2007 Thomas Braxton <kde.braxton@gmail.com>
00004    Copyright (c) 1999 Preston Brown <pbrown@kde.org>
00005    Copyright (c) 1997-1999 Matthias Kalle Dalheimer <kalle@kde.org>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public License
00018    along with this library; see the file COPYING.LIB.  If not, write to
00019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020    Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "kconfig.h"
00024 #include "kconfig_p.h"
00025 
00026 #include <cstdlib>
00027 #include <fcntl.h>
00028 #include <unistd.h>
00029 
00030 #include "kconfigbackend.h"
00031 #include "kconfiggroup.h"
00032 #include <kstringhandler.h>
00033 #include <klocale.h>
00034 #include <kstandarddirs.h>
00035 #include <kurl.h>
00036 #include <kcomponentdata.h>
00037 #include <ktoolinvocation.h>
00038 #include <kaboutdata.h>
00039 #include <kdebug.h>
00040 
00041 #include <qbytearray.h>
00042 #include <qfile.h>
00043 #include <qdir.h>
00044 #include <qdatetime.h>
00045 #include <qrect.h>
00046 #include <qsize.h>
00047 #include <qcolor.h>
00048 #include <QtCore/QProcess>
00049 #include <QtCore/QPointer>
00050 #include <QtCore/QSet>
00051 #include <QtCore/QStack>
00052 
00053 bool KConfigPrivate::mappingsRegistered=false;
00054 
00055 KConfigPrivate::KConfigPrivate(const KComponentData &componentData_, KConfig::OpenFlags flags,
00056                                const char* resource)
00057     : openFlags(flags), resourceType(resource), mBackend(0),
00058       bDynamicBackend(true),  bDirty(false), bReadDefaults(false),
00059       bFileImmutable(false), bForceGlobal(false), bSuppressGlobal(false),
00060       componentData(componentData_), configState(KConfigBase::NoAccess)
00061 {
00062     sGlobalFileName = componentData.dirs()->saveLocation("config") + QLatin1String("kdeglobals");
00063 
00064     static int use_etc_kderc = -1;
00065     if (use_etc_kderc < 0)
00066         use_etc_kderc = getenv("KDE_SKIP_KDERC") != 0 ? 0 : 1; // for unit tests
00067     if (use_etc_kderc) {
00068 
00069         etc_kderc =
00070 #ifdef Q_WS_WIN
00071             QFile::decodeName( qgetenv("WINDIR") + "/kde4rc" );
00072 #else
00073         QLatin1String("/etc/kde4rc");
00074 #endif
00075         if (!KStandardDirs::checkAccess(etc_kderc, R_OK)) {
00076             etc_kderc.clear();
00077         }
00078     }
00079 
00080 //    if (!mappingsRegistered) {
00081 //        KEntryMap tmp;
00082 //        if (!etc_kderc.isEmpty()) {
00083 //            KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, etc_kderc, QLatin1String("INI"));
00084 //            backend->parseConfig( "en_US", tmp, KConfigBackend::ParseDefaults);
00085 //        }
00086 //        const QString kde4rc(QDir::home().filePath(".kde4rc"));
00087 //        if (KStandardDirs::checkAccess(kde4rc, R_OK)) {
00088 //            KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, kde4rc, QLatin1String("INI"));
00089 //            backend->parseConfig( "en_US", tmp, KConfigBackend::ParseOptions());
00090 //        }
00091 //        KConfigBackend::registerMappings(tmp);
00092 //        mappingsRegistered = true;
00093 //    }
00094 
00095     setLocale(KGlobal::hasLocale() ? KGlobal::locale()->language() : KLocale::defaultLanguage());
00096 }
00097 
00098 
00099 bool KConfigPrivate::lockLocal()
00100 {
00101     if (mBackend) {
00102         return mBackend->lock(componentData);
00103     }
00104     // anonymous object - pretend we locked it
00105     return true;
00106 }
00107 
00108 void KConfigPrivate::copyGroup(const QByteArray& source, const QByteArray& destination,
00109                                 KConfigGroup *otherGroup, KConfigBase::WriteConfigFlags flags) const
00110 {
00111     KEntryMap& otherMap = otherGroup->config()->d_ptr->entryMap;
00112     const int len = source.length();
00113     const bool sameName = (destination == source);
00114 
00115     // we keep this bool outside the foreach loop so that if
00116     // the group is empty, we don't end up marking the other config
00117     // as dirty erroneously
00118     bool dirtied = false;
00119 
00120     for (KEntryMap::ConstIterator entryMapIt( entryMap.constBegin() ); entryMapIt != entryMap.constEnd(); ++entryMapIt) {
00121         const QByteArray& group = entryMapIt.key().mGroup;
00122 
00123         if (!group.startsWith(source)) // nothing to do
00124             continue;
00125 
00126         // don't copy groups that start with the same prefix, but are not sub-groups
00127         if (group.length() > len && group[len] != '\x1d')
00128             continue;
00129 
00130         KEntryKey newKey = entryMapIt.key();
00131 
00132         if (flags & KConfigBase::Localized) {
00133             newKey.bLocal = true;
00134         }
00135 
00136         if (!sameName)
00137             newKey.mGroup.replace(0, len, destination);
00138 
00139         KEntry entry = entryMap[ entryMapIt.key() ];
00140         dirtied = entry.bDirty = flags & KConfigBase::Persistent;
00141 
00142         if (flags & KConfigBase::Global) {
00143             entry.bGlobal = true;
00144         }
00145 
00146         otherMap[newKey] = entry;
00147     }
00148 
00149     if (dirtied) {
00150         otherGroup->config()->d_ptr->bDirty = true;
00151     }
00152 }
00153 
00154 KConfig::KConfig( const QString& file, OpenFlags mode,
00155                   const char* resourceType)
00156   : d_ptr(new KConfigPrivate(KGlobal::mainComponent(), mode, resourceType))
00157 {
00158     d_ptr->changeFileName(file, resourceType); // set the local file name
00159 
00160     // read initial information off disk
00161     reparseConfiguration();
00162 }
00163 
00164 KConfig::KConfig( const KComponentData& componentData, const QString& file, OpenFlags mode,
00165                   const char* resourceType)
00166     : d_ptr(new KConfigPrivate(componentData, mode, resourceType))
00167 {
00168     d_ptr->changeFileName(file, resourceType); // set the local file name
00169 
00170     // read initial information off disk
00171     reparseConfiguration();
00172 }
00173 
00174 KConfig::KConfig(const QString& file, const QString& backend, const char* resourceType)
00175     : d_ptr(new KConfigPrivate(KGlobal::mainComponent(), SimpleConfig, resourceType))
00176 {
00177     d_ptr->mBackend = KConfigBackend::create(d_ptr->componentData, file, backend);
00178     d_ptr->bDynamicBackend = false;
00179     d_ptr->changeFileName(file, ""); // set the local file name
00180 
00181     // read initial information off disk
00182     reparseConfiguration();
00183 }
00184 
00185 KConfig::KConfig(KConfigPrivate &d)
00186     : d_ptr(&d)
00187 {
00188 }
00189 
00190 KConfig::~KConfig()
00191 {
00192     Q_D(KConfig);
00193     if (d->bDirty && d->mBackend.isUnique())
00194         sync();
00195     delete d;
00196 }
00197 
00198 const KComponentData& KConfig::componentData() const
00199 {
00200     Q_D(const KConfig);
00201     return d->componentData;
00202 }
00203 
00204 QStringList KConfig::groupList() const
00205 {
00206     Q_D(const KConfig);
00207     QSet<QString> groups;
00208 
00209     for (KEntryMap::ConstIterator entryMapIt( d->entryMap.constBegin() ); entryMapIt != d->entryMap.constEnd(); ++entryMapIt) {
00210         const QByteArray group = entryMapIt.key().mGroup;
00211         if (entryMapIt.key().mKey.isNull() && !group.isEmpty() && group != "<default>" && group != "$Version") {
00212             QString groupname = QString::fromUtf8(group);
00213             groups << groupname.left(groupname.indexOf('\x1d'));
00214         }
00215     }
00216 
00217     return groups.toList();
00218 }
00219 
00220 QStringList KConfigPrivate::groupList(const QByteArray& group) const
00221 {
00222     QByteArray theGroup = group + '\x1d';
00223     QSet<QString> groups;
00224 
00225     for (KEntryMap::ConstIterator entryMapIt( entryMap.constBegin() ); entryMapIt != entryMap.constEnd(); ++entryMapIt)
00226         if (entryMapIt.key().mKey.isNull() && entryMapIt.key().mGroup.startsWith(theGroup)) {
00227             QString groupname = QString::fromUtf8(entryMapIt.key().mGroup.mid(theGroup.length()));
00228             groups << groupname.left(groupname.indexOf('\x1d'));
00229         }
00230 
00231     return groups.toList();
00232 }
00233 
00234 QStringList KConfig::keyList(const QString& aGroup) const
00235 {
00236     Q_D(const KConfig);
00237     QStringList keys;
00238     const QByteArray theGroup(aGroup.isEmpty() ? "<default>" : aGroup.toUtf8());
00239 
00240     const KEntryMapConstIterator theEnd = d->entryMap.constEnd();
00241     KEntryMapConstIterator it = d->entryMap.findEntry(theGroup);
00242     if (it != theEnd) {
00243         ++it; // advance past the special group entry marker
00244 
00245         QSet<QString> tmp;
00246         for (; it != theEnd && it.key().mGroup == theGroup; ++it) {
00247             const KEntryKey& key = it.key();
00248             if (key.mGroup == theGroup && !key.mKey.isNull() && !it->bDeleted)
00249                 tmp << QString::fromUtf8(key.mKey);
00250         }
00251         keys = tmp.toList();
00252     }
00253 
00254     return keys;
00255 }
00256 
00257 QMap<QString,QString> KConfig::entryMap(const QString& aGroup) const
00258 {
00259     Q_D(const KConfig);
00260     QMap<QString, QString> theMap;
00261     const QByteArray theGroup(aGroup.isEmpty() ? "<default>" : aGroup.toUtf8());
00262 
00263     const KEntryMapConstIterator theEnd = d->entryMap.constEnd();
00264     KEntryMapConstIterator it = d->entryMap.findEntry(theGroup, 0, 0);
00265     if (it != theEnd) {
00266         ++it; // advance past the special group entry marker
00267 
00268         for (; it != theEnd && it.key().mGroup == theGroup; ++it) {
00269             // leave the default values and deleted entries out
00270             if (!it->bDeleted && !it.key().bDefault) {
00271                 const QString key = QString::fromUtf8(it.key().mKey.constData());
00272                 // the localized entry should come first, so don't overwrite it
00273                 // with the non-localized entry
00274                 if (!theMap.contains(key))
00275                     theMap.insert(key,QString::fromUtf8(it->mValue.constData()));
00276             }
00277         }
00278     }
00279 
00280     return theMap;
00281 }
00282 
00283 // TODO KDE5: return a bool value
00284 void KConfig::sync()
00285 {
00286     Q_D(KConfig);
00287 
00288     Q_ASSERT(!isImmutable() && !name().isEmpty()); // can't write to an immutable or anonymous file.
00289 
00290     if (d->bDirty && d->mBackend) {
00291         const QByteArray utf8Locale(locale().toUtf8());
00292 
00293         // Create the containing dir, maybe it wasn't there
00294         d->mBackend->createEnclosing();
00295 
00296         // lock the local file
00297         if (d->configState == ReadWrite && !d->lockLocal()) {
00298             qWarning() << "couldn't lock local file";
00299             return;
00300         }
00301 
00302         // Rewrite global/local config only if there is a dirty entry in it.
00303         bool writeGlobals = false;
00304         bool writeLocals = false;
00305         foreach (const KEntry& e, d->entryMap) {
00306             if (e.bDirty) {
00307                 if (e.bGlobal) {
00308                     writeGlobals = true;
00309                 } else {
00310                     writeLocals = true;
00311                 }
00312 
00313                 if (writeGlobals && writeLocals) {
00314                     break;
00315                 }
00316             }
00317         }
00318 
00319         d->bDirty = false; // will revert to true if a config write fails
00320 
00321         if (d->wantGlobals() && writeGlobals) {
00322             KSharedPtr<KConfigBackend> tmp = KConfigBackend::create(componentData(), d->sGlobalFileName);
00323             if (d->configState == ReadWrite && !tmp->lock(componentData())) {
00324                 qWarning() << "couldn't lock global file";
00325                 return;
00326             }
00327             if (!tmp->writeConfig(utf8Locale, d->entryMap, KConfigBackend::WriteGlobal, d->componentData)) {
00328                 d->bDirty = true;
00329                 // TODO KDE5: return false? (to tell the app that writing wasn't possible, e.g.
00330                 // config file is immutable or disk full)
00331             }
00332             if (tmp->isLocked()) {
00333                 tmp->unlock();
00334             }
00335         }
00336 
00337         if (writeLocals) {
00338             if (!d->mBackend->writeConfig(utf8Locale, d->entryMap, KConfigBackend::WriteOptions(), d->componentData)) {
00339                 d->bDirty = true;
00340                 // TODO KDE5: return false? (to tell the app that writing wasn't possible, e.g.
00341                 // config file is immutable or disk full)
00342             }
00343         }
00344         if (d->mBackend->isLocked()) {
00345             d->mBackend->unlock();
00346         }
00347     }
00348 }
00349 
00350 void KConfig::markAsClean()
00351 {
00352     Q_D(KConfig);
00353     d->bDirty = false;
00354 
00355     // clear any dirty flags that entries might have set
00356     const KEntryMapIterator theEnd = d->entryMap.end();
00357     for (KEntryMapIterator it = d->entryMap.begin(); it != theEnd; ++it)
00358         it->bDirty = false;
00359 }
00360 
00361 void KConfig::checkUpdate(const QString &id, const QString &updateFile)
00362 {
00363     const KConfigGroup cg(this, "$Version");
00364     const QString cfg_id = updateFile+':'+id;
00365     QStringList ids = cg.readEntry("update_info", QStringList());
00366     if (!ids.contains(cfg_id)) {
00367         KToolInvocation::kdeinitExecWait("kconf_update", QStringList() << "--check" << updateFile);
00368         reparseConfiguration();
00369     }
00370 }
00371 
00372 KConfig* KConfig::copyTo(const QString &file, KConfig *config) const
00373 {
00374     Q_D(const KConfig);
00375     if (!config)
00376         config = new KConfig(componentData(), QString(), SimpleConfig);
00377     config->d_func()->changeFileName(file, d->resourceType);
00378     config->d_func()->entryMap = d->entryMap;
00379     config->d_func()->bFileImmutable = false;
00380 
00381     const KEntryMapIterator theEnd = config->d_func()->entryMap.end();
00382     for (KEntryMapIterator it = config->d_func()->entryMap.begin(); it != theEnd; ++it)
00383         it->bDirty = true;
00384     config->d_ptr->bDirty = true;
00385 
00386     return config;
00387 }
00388 
00389 QString KConfig::name() const
00390 {
00391     Q_D(const KConfig);
00392     return d->fileName;
00393 }
00394 
00395 void KConfigPrivate::changeFileName(const QString& name, const char* type)
00396 {
00397     fileName = name;
00398 
00399     QString file;
00400     if (name.isEmpty()) {
00401         if (wantDefaults()) { // accessing default app-specific config "appnamerc"
00402             const QString appName = componentData.aboutData()->appName();
00403             if (!appName.isEmpty()) {
00404                 fileName = appName + QLatin1String("rc");
00405                 if (type && *type)
00406                     resourceType = type; // only change it if it's not empty
00407                 file = KStandardDirs::locateLocal(resourceType, fileName, false, componentData);
00408             }
00409         } else if (wantGlobals()) { // accessing "kdeglobals" - XXX used anywhere?
00410             resourceType = "config";
00411             fileName = QLatin1String("kdeglobals");
00412             file = sGlobalFileName;
00413         } // else anonymous config.
00414         // KDE5: remove these magic overloads
00415     } else if (QDir::isAbsolutePath(fileName))
00416         file = fileName;
00417     else {
00418         if (type && *type)
00419             resourceType = type; // only change it if it's not empty
00420         file = KStandardDirs::locateLocal(resourceType, fileName, false, componentData);
00421     }
00422 
00423     if (file.isEmpty()) {
00424         openFlags = KConfig::SimpleConfig;
00425         return;
00426     }
00427 
00428     bSuppressGlobal = (file == sGlobalFileName);
00429 
00430     if (bDynamicBackend || !mBackend) // allow dynamic changing of backend
00431         mBackend = KConfigBackend::create(componentData, file);
00432     else
00433         mBackend->setFilePath(file);
00434 
00435     configState = mBackend->accessMode();
00436 }
00437 
00438 void KConfig::reparseConfiguration()
00439 {
00440     Q_D(KConfig);
00441     // Don't lose pending changes
00442     if (!d->isReadOnly() && d->bDirty)
00443         sync();
00444 
00445     d->entryMap.clear();
00446 
00447     d->bFileImmutable = false;
00448 
00449     // Parse all desired files from the least to the most specific.
00450     if (d->wantGlobals())
00451         d->parseGlobalFiles();
00452 
00453     d->parseConfigFiles();
00454 }
00455 
00456 
00457 QStringList KConfigPrivate::getGlobalFiles() const
00458 {
00459     const KStandardDirs *const dirs = componentData.dirs();
00460     QStringList globalFiles;
00461     foreach (const QString& dir1, dirs->findAllResources("config", QLatin1String("kdeglobals")))
00462         globalFiles.push_front(dir1);
00463     foreach (const QString& dir2, dirs->findAllResources("config", QLatin1String("system.kdeglobals")))
00464         globalFiles.push_front(dir2);
00465     if (!etc_kderc.isEmpty())
00466         globalFiles.push_front(etc_kderc);
00467     return globalFiles;
00468 }
00469 
00470 void KConfigPrivate::parseGlobalFiles()
00471 {
00472     QStringList globalFiles = getGlobalFiles();
00473 //    qDebug() << "parsing global files" << globalFiles;
00474 
00475     // TODO: can we cache the values in etc_kderc / other global files
00476     //       on a per-application basis?
00477     const QByteArray utf8Locale = locale.toUtf8();
00478     foreach(const QString& file, globalFiles) {
00479         KConfigBackend::ParseOptions parseOpts = KConfigBackend::ParseGlobal|KConfigBackend::ParseExpansions;
00480         if (file != sGlobalFileName)
00481             parseOpts |= KConfigBackend::ParseDefaults;
00482 
00483         KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, file);
00484         if ( backend->parseConfig( utf8Locale, entryMap, parseOpts) == KConfigBackend::ParseImmutable)
00485             break;
00486     }
00487 }
00488 
00489 void KConfigPrivate::parseConfigFiles()
00490 {
00491     // can only read the file if there is a backend and a file name
00492     if (mBackend && !fileName.isEmpty()) {
00493 
00494         bFileImmutable = false;
00495 
00496         QList<QString> files;
00497         if (wantDefaults()) {
00498             if (bSuppressGlobal) {
00499                 files = getGlobalFiles();
00500             } else {
00501                 foreach (const QString& f, componentData.dirs()->findAllResources(
00502                                                     resourceType, fileName))
00503                     files.prepend(f);
00504             }
00505         } else {
00506             files << mBackend->filePath();
00507         }
00508         if (!isSimple())
00509             files = extraFiles.toList() + files;
00510 
00511 //        qDebug() << "parsing local files" << files;
00512 
00513         const QByteArray utf8Locale = locale.toUtf8();
00514         foreach(const QString& file, files) {
00515             if (file == mBackend->filePath()) {
00516                 switch (mBackend->parseConfig(utf8Locale, entryMap, KConfigBackend::ParseExpansions)) {
00517                 case KConfigBackend::ParseOk:
00518                     break;
00519                 case KConfigBackend::ParseImmutable:
00520                     bFileImmutable = true;
00521                     break;
00522                 case KConfigBackend::ParseOpenError:
00523                     configState = KConfigBase::NoAccess;
00524                     break;
00525                 }
00526             } else {
00527                 KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, file);
00528                 bFileImmutable = (backend->parseConfig(utf8Locale, entryMap,
00529                                         KConfigBackend::ParseDefaults|KConfigBackend::ParseExpansions)
00530                                   == KConfigBackend::ParseImmutable);
00531             }
00532 
00533             if (bFileImmutable)
00534                 break;
00535         }
00536         if (componentData.dirs()->isRestrictedResource(resourceType, fileName))
00537             bFileImmutable = true;
00538     }
00539 }
00540 
00541 KConfig::AccessMode KConfig::accessMode() const
00542 {
00543     Q_D(const KConfig);
00544     return d->configState;
00545 }
00546 
00547 void KConfig::addConfigSources(const QStringList& files)
00548 {
00549     Q_D(KConfig);
00550     foreach(const QString& file, files) {
00551         d->extraFiles.push(file);
00552     }
00553 
00554     if (!files.isEmpty()) {
00555         reparseConfiguration();
00556     }
00557 }
00558 
00559 QString KConfig::locale() const
00560 {
00561     Q_D(const KConfig);
00562     return d->locale;
00563 }
00564 
00565 bool KConfigPrivate::setLocale(const QString& aLocale)
00566 {
00567     if (aLocale != locale) {
00568         locale = aLocale;
00569         return true;
00570     }
00571     return false;
00572 }
00573 
00574 bool KConfig::setLocale(const QString& locale)
00575 {
00576     Q_D(KConfig);
00577     if (d->setLocale(locale)) {
00578         reparseConfiguration();
00579         return true;
00580     }
00581     return false;
00582 }
00583 
00584 void KConfig::setReadDefaults(bool b)
00585 {
00586     Q_D(KConfig);
00587     d->bReadDefaults = b;
00588 }
00589 
00590 bool KConfig::readDefaults() const
00591 {
00592     Q_D(const KConfig);
00593     return d->bReadDefaults;
00594 }
00595 
00596 bool KConfig::isImmutable() const
00597 {
00598     Q_D(const KConfig);
00599     return d->bFileImmutable;
00600 }
00601 
00602 bool KConfig::isGroupImmutableImpl(const QByteArray& aGroup) const
00603 {
00604     Q_D(const KConfig);
00605     return isImmutable() || d->entryMap.getEntryOption(aGroup, 0, 0, KEntryMap::EntryImmutable);
00606 }
00607 
00608 void KConfig::setForceGlobal(bool b)
00609 {
00610     Q_D(KConfig);
00611     d->bForceGlobal = b;
00612 }
00613 
00614 bool KConfig::forceGlobal() const
00615 {
00616     Q_D(const KConfig);
00617     return d->bForceGlobal;
00618 }
00619 
00620 KConfigGroup KConfig::groupImpl(const QByteArray &group)
00621 {
00622     return KConfigGroup(this, group.constData());
00623 }
00624 
00625 const KConfigGroup KConfig::groupImpl(const QByteArray &group) const
00626 {
00627     return KConfigGroup(this, group.constData());
00628 }
00629 
00630 KEntryMap::EntryOptions convertToOptions(KConfig::WriteConfigFlags flags)
00631 {
00632     KEntryMap::EntryOptions options=0;
00633 
00634     if (flags&KConfig::Persistent)
00635         options |= KEntryMap::EntryDirty;
00636     if (flags&KConfig::Global)
00637         options |= KEntryMap::EntryGlobal;
00638     if (flags&KConfig::Localized)
00639         options |= KEntryMap::EntryLocalized;
00640     return options;
00641 }
00642 
00643 void KConfig::deleteGroupImpl(const QByteArray &aGroup, WriteConfigFlags flags)
00644 {
00645     Q_D(KConfig);
00646     KEntryMap::EntryOptions options = convertToOptions(flags)|KEntryMap::EntryDeleted;
00647 
00648     QByteArray theGroup = aGroup + '\x1d';
00649     QSet<QByteArray> groups;
00650     groups << aGroup;
00651 
00652     for (KEntryMap::ConstIterator entryMapIt( d->entryMap.constBegin() ); entryMapIt != d->entryMap.constEnd(); ++entryMapIt) {
00653         if (entryMapIt.key().mKey.isNull() && entryMapIt.key().mGroup.startsWith(theGroup)) {
00654             groups << entryMapIt.key().mGroup;
00655         }
00656     }
00657 
00658     foreach (const QByteArray& group, groups) {
00659         const QStringList keys = keyList(QString::fromUtf8(group));
00660         foreach (const QString& _key, keys) {
00661             const QByteArray &key = _key.toUtf8();
00662             if (d->canWriteEntry(group, key.constData())) {
00663                 d->entryMap.setEntry(group, key, QByteArray(), options);
00664                 d->bDirty = true;
00665             }
00666         }
00667     }
00668 }
00669 
00670 bool KConfig::isConfigWritable(bool warnUser)
00671 {
00672     Q_D(KConfig);
00673     bool allWritable = (d->mBackend.isNull()? false: d->mBackend->isWritable());
00674 
00675     if (warnUser && !allWritable) {
00676         QString errorMsg;
00677         if (!d->mBackend.isNull()) // TODO how can be it be null? Set errorMsg appropriately
00678             errorMsg = d->mBackend->nonWritableErrorMessage();
00679 
00680         // Note: We don't ask the user if we should not ask this question again because we can't save the answer.
00681         errorMsg += i18n("Please contact your system administrator.");
00682         QString cmdToExec = KStandardDirs::findExe(QString("kdialog"));
00683         if (!cmdToExec.isEmpty() && componentData().isValid())
00684         {
00685             QProcess::execute(cmdToExec,QStringList() << "--title" << componentData().componentName()
00686                     << "--msgbox" << errorMsg);
00687         }
00688     }
00689 
00690     d->configState = allWritable ?  ReadWrite : ReadOnly; // update the read/write status
00691 
00692     return allWritable;
00693 }
00694 
00695 bool KConfig::hasGroupImpl(const QByteArray& aGroup) const
00696 {
00697     Q_D(const KConfig);
00698 
00699     if (d->entryMap.hasEntry(aGroup)) return true;
00700 
00701     QByteArray subGroupMarker = aGroup + '\x1d';
00702     // Because this group could have only subgroups but no entries we have to
00703     // search for group markers
00704     for (KEntryMap::ConstIterator entryMapIt( d->entryMap.constBegin() ); entryMapIt != d->entryMap.constEnd(); ++entryMapIt) {
00705         if (entryMapIt.key().mGroup.startsWith(subGroupMarker)) {
00706             return true;
00707         }
00708     }
00709     return false;
00710 }
00711 
00712 bool KConfigPrivate::canWriteEntry(const QByteArray& group, const char* key, bool isDefault) const
00713 {
00714     if (bFileImmutable ||
00715         entryMap.getEntryOption(group, key, KEntryMap::SearchLocalized, KEntryMap::EntryImmutable))
00716         return isDefault;
00717     return true;
00718 }
00719 
00720 void KConfigPrivate::putData( const QByteArray& group, const char* key,
00721                       const QByteArray& value, KConfigBase::WriteConfigFlags flags, bool expand)
00722 {
00723     KEntryMap::EntryOptions options = convertToOptions(flags);
00724 
00725     if (bForceGlobal)
00726         options |= KEntryMap::EntryGlobal;
00727     if (expand)
00728         options |= KEntryMap::EntryExpansion;
00729 
00730     if (value.isNull()) // deleting entry
00731         options |= KEntryMap::EntryDeleted;
00732 
00733     bool dirtied = entryMap.setEntry(group, key, value, options);
00734     if (dirtied && (flags & KConfigBase::Persistent))
00735         bDirty = true;
00736 }
00737 
00738 QByteArray KConfigPrivate::lookupData(const QByteArray& group, const char* key,
00739                                       KEntryMap::SearchFlags flags) const
00740 {
00741     if (bReadDefaults)
00742         flags |= KEntryMap::SearchDefaults;
00743     const KEntryMapConstIterator it = entryMap.findEntry(group, key, flags);
00744     if (it == entryMap.constEnd())
00745         return QByteArray();
00746     return it->mValue;
00747 }
00748 
00749 QString KConfigPrivate::lookupData(const QByteArray& group, const char* key,
00750                                    KEntryMap::SearchFlags flags, bool *expand) const
00751 {
00752     if (bReadDefaults)
00753         flags |= KEntryMap::SearchDefaults;
00754     return entryMap.getEntry(group, key, QString(), flags, expand);
00755 }
00756 
00757 void KConfig::virtual_hook(int /*id*/, void* /*data*/)
00758 {
00759     /* nothing */
00760 }
00761 

KDECore

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal