• Skip to content
  • Skip to link menu
KDE 4.1 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), componentData(componentData_),
00060       configState(KConfigBase::NoAccess)
00061 {
00062     sGlobalFileName = componentData.dirs()->saveLocation("config") +
00063                           QString::fromLatin1("kdeglobals");
00064     const QString etc_kderc =
00065 #ifdef Q_WS_WIN
00066         QFile::decodeName( qgetenv("WINDIR") + "/kde4rc" );
00067 #else
00068         QLatin1String("/etc/kde4rc");
00069 #endif
00070     KEntryMap tmp;
00071     // first entry is always /etc/kderc or empty if cannot read
00072     if (KStandardDirs::checkAccess(etc_kderc, R_OK)) {
00073         if (!mappingsRegistered) {
00074             KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, etc_kderc, QLatin1String("INI"));
00075             backend->parseConfig( "en_US", tmp, KConfigBackend::ParseDefaults);
00076         }
00077     } else {
00078         mappingsRegistered = true;
00079     }
00080 
00081     if (!mappingsRegistered) {
00082         const QString kde4rc(QDir::home().filePath(".kde4rc"));
00083         if (KStandardDirs::checkAccess(kde4rc, R_OK)) {
00084             KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, kde4rc, QLatin1String("INI"));
00085             backend->parseConfig( "en_US", tmp, KConfigBackend::ParseOptions());
00086         }
00087         KConfigBackend::registerMappings(tmp);
00088         mappingsRegistered = true;
00089     }
00090     setLocale(KGlobal::hasLocale() ? KGlobal::locale()->language() : KLocale::defaultLanguage());
00091 }
00092 
00093 
00094 bool KConfigPrivate::lockLocal()
00095 {
00096     if (mBackend) {
00097         if (fileName == QLatin1String("kdeglobals")) { // we don't want to lock "kdeglobals" twice
00098             if (wantGlobals()) // "kdeglobals" will be locked with the global lock
00099                 return true; // so pretend we locked it here
00100         }
00101         return mBackend->lock(componentData);
00102     }
00103     // anonymous object - pretend we locked it
00104     return true;
00105 }
00106 
00107 void KConfigPrivate::copyGroup(const QByteArray& source, const QByteArray& destination,
00108                                 KConfigGroup *otherGroup, KConfigBase::WriteConfigFlags flags) const
00109 {
00110     KEntryMap& otherMap = otherGroup->config()->d_ptr->entryMap;
00111     const int len = source.length();
00112     const bool sameName = (destination == source);
00113 
00114     // we keep this bool outside the foreach loop so that if
00115     // the group is empty, we don't end up marking the other config
00116     // as dirty erroneously
00117     bool dirtied = false;
00118 
00119     for (KEntryMap::ConstIterator entryMapIt( entryMap.constBegin() ); entryMapIt != entryMap.constEnd(); ++entryMapIt) {
00120         const QByteArray& group = entryMapIt.key().mGroup;
00121 
00122         if (!group.startsWith(source)) // nothing to do
00123             continue;
00124 
00125         // don't copy groups that start with the same prefix, but are not sub-groups
00126         if (group.length() > len && group[len] != '\x1d')
00127             continue;
00128 
00129         KEntryKey newKey = entryMapIt.key();
00130 
00131         if (flags & KConfigBase::Localized) {
00132             newKey.bLocal = true;
00133         }
00134 
00135         if (!sameName)
00136             newKey.mGroup.replace(0, len, destination);
00137 
00138         KEntry entry = entryMap[ entryMapIt.key() ];
00139         dirtied = entry.bDirty = flags & KConfigBase::Persistent;
00140 
00141         if (flags & KConfigBase::Global) {
00142             entry.bGlobal = true;
00143         }
00144 
00145         otherMap[newKey] = entry;
00146     }
00147 
00148     if (dirtied) {
00149         otherGroup->config()->d_ptr->bDirty = true;
00150     }
00151 }
00152 
00153 KConfig::KConfig( const QString& file, OpenFlags mode,
00154                   const char* resourceType)
00155   : d_ptr(new KConfigPrivate(KGlobal::mainComponent(), mode, resourceType))
00156 {
00157     d_ptr->changeFileName(file, resourceType); // set the local file name
00158 
00159     // read initial information off disk
00160     reparseConfiguration();
00161 }
00162 
00163 KConfig::KConfig( const KComponentData& componentData, const QString& file, OpenFlags mode,
00164                   const char* resourceType)
00165     : d_ptr(new KConfigPrivate(componentData, mode, resourceType))
00166 {
00167     d_ptr->changeFileName(file, resourceType); // set the local file name
00168 
00169     // read initial information off disk
00170     reparseConfiguration();
00171 }
00172 
00173 KConfig::KConfig(const QString& file, const QString& backend, const char* resourceType)
00174     : d_ptr(new KConfigPrivate(KGlobal::mainComponent(), SimpleConfig, resourceType))
00175 {
00176     d_ptr->mBackend = KConfigBackend::create(d_ptr->componentData, file, backend);
00177     d_ptr->bDynamicBackend = false;
00178     d_ptr->changeFileName(file, ""); // set the local file name
00179 
00180     // read initial information off disk
00181     reparseConfiguration();
00182 }
00183 
00184 KConfig::KConfig(KConfigPrivate &d)
00185     : d_ptr(&d)
00186 {
00187 }
00188 
00189 KConfig::~KConfig()
00190 {
00191     Q_D(KConfig);
00192     if (d->bDirty && d->mBackend.isUnique())
00193         sync();
00194     delete d;
00195 }
00196 
00197 const KComponentData& KConfig::componentData() const
00198 {
00199     Q_D(const KConfig);
00200     return d->componentData;
00201 }
00202 
00203 QStringList KConfig::groupList() const
00204 {
00205     Q_D(const KConfig);
00206     QStringList groups;
00207 
00208     for (KEntryMap::ConstIterator entryMapIt( d->entryMap.constBegin() ); entryMapIt != d->entryMap.constEnd(); ++entryMapIt)
00209         if (entryMapIt.key().mKey.isNull() && !entryMapIt.key().mGroup.isEmpty() &&
00210             entryMapIt.key().mGroup != "<default>" && entryMapIt.key().mGroup != "$Version")
00211             groups << QString::fromUtf8(entryMapIt.key().mGroup);
00212 
00213     return groups;
00214 }
00215 
00216 QStringList KConfigPrivate::groupList(const QByteArray& group) const
00217 {
00218     QByteArray theGroup = group + '\x1d';
00219     QSet<QString> groups;
00220 
00221     for (KEntryMap::ConstIterator entryMapIt( entryMap.constBegin() ); entryMapIt != entryMap.constEnd(); ++entryMapIt)
00222         if (entryMapIt.key().mKey.isNull() && entryMapIt.key().mGroup.startsWith(theGroup))
00223         {
00224             QString groupname = QString::fromUtf8(entryMapIt.key().mGroup.mid(theGroup.length()));
00225             groups << groupname.left(groupname.indexOf('\x1d'));
00226         }
00227 
00228     return groups.toList();
00229 }
00230 
00231 QStringList KConfig::keyList(const QString& aGroup) const
00232 {
00233     Q_D(const KConfig);
00234     QStringList keys;
00235     const QByteArray theGroup(aGroup.isEmpty() ? "<default>" : aGroup.toUtf8());
00236 
00237     const KEntryMapConstIterator theEnd = d->entryMap.constEnd();
00238     KEntryMapConstIterator it = d->entryMap.findEntry(theGroup);
00239     if (it != theEnd) {
00240         ++it; // advance past the special group entry marker
00241 
00242         QSet<QString> tmp;
00243         for (; it != theEnd && it.key().mGroup == theGroup; ++it) {
00244             const KEntryKey& key = it.key();
00245             if (key.mGroup == theGroup && !key.mKey.isNull() && !it->bDeleted)
00246                 tmp << QString::fromUtf8(key.mKey);
00247         }
00248         keys = tmp.toList();
00249     }
00250 
00251     return keys;
00252 }
00253 
00254 QMap<QString,QString> KConfig::entryMap(const QString& aGroup) const
00255 {
00256     Q_D(const KConfig);
00257     QMap<QString, QString> theMap;
00258     const QByteArray theGroup(aGroup.isEmpty() ? "<default>" : aGroup.toUtf8());
00259 
00260     const KEntryMapConstIterator theEnd = d->entryMap.constEnd();
00261     KEntryMapConstIterator it = d->entryMap.findEntry(theGroup, 0, 0);
00262     if (it != theEnd) {
00263         ++it; // advance past the special group entry marker
00264 
00265         for (; it != theEnd && it.key().mGroup == theGroup; ++it) {
00266             // leave the default values and deleted entries out
00267             if (!it->bDeleted && !it.key().bDefault) {
00268                 const QString key = QString::fromUtf8(it.key().mKey.constData());
00269                 // the localized entry should come first, so don't overwrite it
00270                 // with the non-localized entry
00271                 if (!theMap.contains(key))
00272                     theMap.insert(key,QString::fromUtf8(it->mValue.constData()));
00273             }
00274         }
00275     }
00276 
00277     return theMap;
00278 }
00279 
00280 void KConfig::sync()
00281 {
00282     Q_D(KConfig);
00283 
00284     Q_ASSERT(!isImmutable() && !name().isEmpty()); // can't write to an immutable or anonymous file.
00285 
00286     if (d->bDirty && d->mBackend) {
00287         const QByteArray utf8Locale(locale().toUtf8());
00288 
00289         // Check if we can write to the local file.
00290         if (!d->mBackend->isWritable()) {
00291             // Create the containing dir, maybe it wasn't there
00292             d->mBackend->createEnclosing();
00293         }
00294 
00295         // lock the local file
00296         if (d->configState == ReadWrite && !d->lockLocal()) {
00297             qWarning() << "couldn't lock local file";
00298             return;
00299         }
00300 
00301         // Rewrite global/local config only if there is a dirty entry in it.
00302         bool writeGlobals = false;
00303         bool writeLocals = false;
00304         foreach (const KEntry& e, d->entryMap) {
00305             if (e.bDirty) {
00306                 if (e.bGlobal) {
00307                     writeGlobals = true;
00308                 } else {
00309                     writeLocals = true;
00310                 }
00311 
00312                 if (writeGlobals && writeLocals) {
00313                     break;
00314                 }
00315             }
00316         }
00317 
00318         d->bDirty = false; // will revert to true if a config write fails
00319 
00320         if (d->wantGlobals() && writeGlobals) {
00321             KSharedPtr<KConfigBackend> tmp = KConfigBackend::create(componentData(), d->sGlobalFileName);
00322             if (d->configState == ReadWrite && !tmp->lock(componentData())) {
00323                 qWarning() << "couldn't lock global file";
00324                 return;
00325             }
00326             if (!tmp->writeConfig(utf8Locale, d->entryMap, KConfigBackend::WriteGlobal, d->componentData)) {
00327                 d->bDirty = true;
00328             }
00329             if (tmp->isLocked()) {
00330                 tmp->unlock();
00331             }
00332         }
00333 
00334         if (writeLocals) {
00335             if (!d->mBackend->writeConfig(utf8Locale, d->entryMap, KConfigBackend::WriteOptions(), d->componentData)) {
00336                 d->bDirty = true;
00337             }
00338         }
00339         if (d->mBackend->isLocked()) {
00340             d->mBackend->unlock();
00341         }
00342     }
00343 }
00344 
00345 void KConfig::markAsClean()
00346 {
00347     Q_D(KConfig);
00348     d->bDirty = false;
00349 
00350     // clear any dirty flags that entries might have set
00351     const KEntryMapIterator theEnd = d->entryMap.end();
00352     for (KEntryMapIterator it = d->entryMap.begin(); it != theEnd; ++it)
00353         it->bDirty = false;
00354 }
00355 
00356 void KConfig::checkUpdate(const QString &id, const QString &updateFile)
00357 {
00358     const KConfigGroup cg(this, "$Version");
00359     const QString cfg_id = updateFile+':'+id;
00360     QStringList ids = cg.readEntry("update_info", QStringList());
00361     if (!ids.contains(cfg_id)) {
00362         KToolInvocation::kdeinitExecWait("kconf_update", QStringList() << "--check" << updateFile);
00363         reparseConfiguration();
00364     }
00365 }
00366 
00367 KConfig* KConfig::copyTo(const QString &file, KConfig *config) const
00368 {
00369     Q_D(const KConfig);
00370     if (!config)
00371         config = new KConfig(componentData(), QString(), SimpleConfig);
00372     config->d_func()->changeFileName(file, d->resourceType);
00373     config->d_func()->entryMap = d->entryMap;
00374     config->d_func()->bFileImmutable = false;
00375 
00376     const KEntryMapIterator theEnd = config->d_func()->entryMap.end();
00377     for (KEntryMapIterator it = config->d_func()->entryMap.begin(); it != theEnd; ++it)
00378         it->bDirty = true;
00379     config->d_ptr->bDirty = true;
00380 
00381     return config;
00382 }
00383 
00384 QString KConfig::name() const
00385 {
00386     Q_D(const KConfig);
00387     return d->fileName;
00388 }
00389 
00390 void KConfigPrivate::changeFileName(const QString& name, const char* type)
00391 {
00392     fileName = name;
00393 
00394     QString file;
00395     if (name.isEmpty()) {
00396         if (wantDefaults()) { // accessing default app-specific config "appnamerc"
00397             const QString appName = componentData.aboutData()->appName();
00398             if (!appName.isEmpty()) {
00399                 fileName = appName + QLatin1String("rc");
00400                 if (type && *type)
00401                     resourceType = type; // only change it if it's not empty
00402                 file = KStandardDirs::locateLocal(resourceType, fileName, componentData);
00403             }
00404         } else if (wantGlobals()) { // accessing "kdeglobals"
00405             resourceType = "config";
00406             fileName = QLatin1String("kdeglobals");
00407             file = sGlobalFileName;
00408         }
00409     } else if (QDir::isAbsolutePath(fileName))
00410         file = fileName;
00411     else {
00412         if (type && *type)
00413             resourceType = type; // only change it if it's not empty
00414         file = KStandardDirs::locateLocal(resourceType, fileName, componentData);
00415 
00416         if (fileName == QLatin1String("kdeglobals"))
00417             openFlags |= KConfig::IncludeGlobals;
00418     }
00419 
00420     bForceGlobal = (fileName == QLatin1String("kdeglobals"));
00421 
00422     if (file.isEmpty()) {
00423         openFlags = KConfig::SimpleConfig;
00424         return;
00425     }
00426 
00427     if (bDynamicBackend || !mBackend) // allow dynamic changing of backend
00428         mBackend = KConfigBackend::create(componentData, file);
00429     else
00430         mBackend->setFilePath(file);
00431 
00432     configState = mBackend->accessMode();
00433 }
00434 
00435 void KConfig::reparseConfiguration()
00436 {
00437     Q_D(KConfig);
00438     // Don't lose pending changes
00439     if (!d->isReadOnly() && d->bDirty)
00440         sync();
00441 
00442     d->entryMap.clear();
00443 
00444     d->bFileImmutable = false;
00445 
00446     // Parse all desired files from the least to the most specific.
00447     if (d->wantGlobals())
00448         d->parseGlobalFiles();
00449 
00450     d->parseConfigFiles();
00451 }
00452 
00453 void KConfigPrivate::parseGlobalFiles()
00454 {
00455     QStringList globalFiles;
00456 
00457     if (wantGlobals()) {
00458         const KStandardDirs *const dirs = componentData.dirs();
00459         foreach(const QString& dir, dirs->findAllResources("config", QLatin1String("kdeglobals")) +
00460                                     dirs->findAllResources("config", QLatin1String("system.kdeglobals")))
00461             globalFiles.push_front(dir);
00462     }
00463     const QString etc_kderc =
00464 #ifdef Q_WS_WIN
00465         QFile::decodeName( QByteArray(::getenv("WINDIR")) + "\\kde4rc" );
00466 #else
00467         QLatin1String("/etc/kde4rc");
00468 #endif
00469     KEntryMap tmp;
00470     // first entry is always /etc/kderc or empty if cannot read
00471     if (KStandardDirs::checkAccess(etc_kderc, R_OK)) {
00472         if (!globalFiles.contains(etc_kderc))
00473             globalFiles.push_front(etc_kderc);
00474     } else {
00475         globalFiles.push_front(QString());
00476     }
00477 
00478 //    qDebug() << "parsing global files" << globalFiles;
00479 
00480     const QByteArray utf8Locale = locale.toUtf8();
00481     foreach(const QString& file, globalFiles) {
00482         KConfigBackend::ParseOptions parseOpts = KConfigBackend::ParseGlobal|KConfigBackend::ParseExpansions;
00483         if (file != sGlobalFileName)
00484             parseOpts |= KConfigBackend::ParseDefaults;
00485 
00486         KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, file);
00487         if ( backend->parseConfig( utf8Locale, entryMap, parseOpts) == KConfigBackend::ParseImmutable)
00488             break;
00489     }
00490 }
00491 
00492 void KConfigPrivate::parseConfigFiles()
00493 {
00494     if (fileName == QLatin1String("kdeglobals") && wantGlobals())
00495         return; // already parsed in parseGlobalFiles()
00496 
00497     // can only read the file if there is a backend and a file name
00498     if (mBackend && !fileName.isEmpty()) {
00499 
00500         bFileImmutable = false;
00501         QList<QString> files;
00502 
00503         if (wantDefaults())
00504             foreach (const QString& f, componentData.dirs()->findAllResources(resourceType, fileName))
00505                 files.prepend(f);
00506         else
00507             files << mBackend->filePath();
00508 
00509         if (!isSimple())
00510             files = extraFiles.toList() + files;
00511 
00512 //        qDebug() << "parsing local files" << files;
00513 
00514         const QByteArray utf8Locale = locale.toUtf8();
00515         foreach(const QString& file, files) {
00516             if (file == mBackend->filePath()) {
00517                 switch (mBackend->parseConfig(utf8Locale, entryMap, KConfigBackend::ParseExpansions)) {
00518                 case KConfigBackend::ParseOk:
00519                     break;
00520                 case KConfigBackend::ParseImmutable:
00521                     bFileImmutable = true;
00522                     break;
00523                 case KConfigBackend::ParseOpenError:
00524                     configState = KConfigBase::NoAccess;
00525                     break;
00526                 }
00527             } else {
00528                 KSharedPtr<KConfigBackend> backend = KConfigBackend::create(componentData, file);
00529                 bFileImmutable = (backend->parseConfig(utf8Locale, entryMap,
00530                                         KConfigBackend::ParseDefaults|KConfigBackend::ParseExpansions)
00531                                   == KConfigBackend::ParseImmutable);
00532             }
00533 
00534             if (bFileImmutable)
00535                 break;
00536         }
00537         if (componentData.dirs()->isRestrictedResource(resourceType, fileName))
00538             bFileImmutable = true;
00539     }
00540 }
00541 
00542 KConfig::AccessMode KConfig::accessMode() const
00543 {
00544     Q_D(const KConfig);
00545     return d->configState;
00546 }
00547 
00548 void KConfig::addConfigSources(const QStringList& files)
00549 {
00550     Q_D(KConfig);
00551     foreach(const QString& file, files) {
00552         d->extraFiles.push(file);
00553     }
00554 
00555     if (!files.isEmpty()) {
00556         reparseConfiguration();
00557     }
00558 }
00559 
00560 QString KConfig::locale() const
00561 {
00562     Q_D(const KConfig);
00563     return d->locale;
00564 }
00565 
00566 bool KConfigPrivate::setLocale(const QString& aLocale)
00567 {
00568     if (aLocale != locale) {
00569         locale = aLocale;
00570         return true;
00571     }
00572     return false;
00573 }
00574 
00575 bool KConfig::setLocale(const QString& locale)
00576 {
00577     Q_D(KConfig);
00578     if (d->setLocale(locale)) {
00579         reparseConfiguration();
00580         return true;
00581     }
00582     return false;
00583 }
00584 
00585 void KConfig::setReadDefaults(bool b)
00586 {
00587     Q_D(KConfig);
00588     d->bReadDefaults = b;
00589 }
00590 
00591 bool KConfig::readDefaults() const
00592 {
00593     Q_D(const KConfig);
00594     return d->bReadDefaults;
00595 }
00596 
00597 bool KConfig::isImmutable() const
00598 {
00599     Q_D(const KConfig);
00600     return d->bFileImmutable;
00601 }
00602 
00603 bool KConfig::isGroupImmutableImpl(const QByteArray& aGroup) const
00604 {
00605     Q_D(const KConfig);
00606     return isImmutable()|d->entryMap.getEntryOption(aGroup, 0, 0, KEntryMap::EntryImmutable);
00607 }
00608 
00609 void KConfig::setForceGlobal(bool b)
00610 {
00611     Q_D(KConfig);
00612     d->bForceGlobal = b;
00613 }
00614 
00615 bool KConfig::forceGlobal() const
00616 {
00617     Q_D(const KConfig);
00618     return d->bForceGlobal;
00619 }
00620 
00621 KConfigGroup KConfig::groupImpl(const QByteArray &group)
00622 {
00623     return KConfigGroup(this, group.constData());
00624 }
00625 
00626 const KConfigGroup KConfig::groupImpl(const QByteArray &group) const
00627 {
00628     return KConfigGroup(this, group.constData());
00629 }
00630 
00631 KEntryMap::EntryOptions convertToOptions(KConfig::WriteConfigFlags flags)
00632 {
00633     KEntryMap::EntryOptions options=0;
00634 
00635     if (flags&KConfig::Persistent)
00636         options |= KEntryMap::EntryDirty;
00637     if (flags&KConfig::Global)
00638         options |= KEntryMap::EntryGlobal;
00639     if (flags&KConfig::Localized)
00640         options |= KEntryMap::EntryLocalized;
00641     return options;
00642 }
00643 
00644 void KConfig::deleteGroupImpl(const QByteArray &aGroup, WriteConfigFlags flags)
00645 {
00646     Q_D(KConfig);
00647     KEntryMap::EntryOptions options = convertToOptions(flags)|KEntryMap::EntryDeleted;
00648 
00649     QByteArray theGroup = aGroup + '\x1d';
00650     QSet<QByteArray> groups;
00651     groups << aGroup;
00652 
00653     for (KEntryMap::ConstIterator entryMapIt( d->entryMap.constBegin() ); entryMapIt != d->entryMap.constEnd(); ++entryMapIt) {
00654         if (entryMapIt.key().mKey.isNull() && entryMapIt.key().mGroup.startsWith(theGroup)) {
00655             groups << entryMapIt.key().mGroup;
00656         }
00657     }
00658 
00659     foreach (const QByteArray& group, groups) {
00660         const QStringList keys = keyList(QString::fromUtf8(group));
00661         foreach (const QString& key, keys) {
00662             if (d->canWriteEntry(group, key.toUtf8().constData())) {
00663                 d->entryMap.setEntry(group, key.toUtf8(), 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.toLocal8Bit());
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     return d->entryMap.hasEntry(aGroup);
00699 }
00700 
00701 bool KConfigPrivate::canWriteEntry(const QByteArray& group, const char* key, bool isDefault) const
00702 {
00703     if (bFileImmutable ||
00704         entryMap.getEntryOption(group, key, KEntryMap::SearchLocalized, KEntryMap::EntryImmutable))
00705         return isDefault;
00706     return true;
00707 }
00708 
00709 void KConfigPrivate::putData( const QByteArray& group, const char* key,
00710                       const QByteArray& value, KConfigBase::WriteConfigFlags flags, bool expand)
00711 {
00712     KEntryMap::EntryOptions options = convertToOptions(flags);
00713     if (bForceGlobal)
00714         options |= KEntryMap::EntryGlobal;
00715     if (expand)
00716         options |= KEntryMap::EntryExpansion;
00717 
00718     if (value.isNull()) // deleting entry
00719         options |= KEntryMap::EntryDeleted;
00720 
00721     entryMap.setEntry(group, key, value, options);
00722 
00723     if (flags & KConfigBase::Persistent)
00724         bDirty = true;
00725 }
00726 
00727 QByteArray KConfigPrivate::lookupData(const QByteArray& group, const char* key,
00728                                       KEntryMap::SearchFlags flags) const
00729 {
00730     if (bReadDefaults)
00731         flags |= KEntryMap::SearchDefaults;
00732     const KEntryMapConstIterator it = entryMap.findEntry(group, key, flags);
00733     if (it == entryMap.constEnd())
00734         return QByteArray();
00735     return it->mValue;
00736 }
00737 
00738 QString KConfigPrivate::lookupData(const QByteArray& group, const char* key,
00739                                    KEntryMap::SearchFlags flags, bool *expand) const
00740 {
00741     if (bReadDefaults)
00742         flags |= KEntryMap::SearchDefaults;
00743     return entryMap.getEntry(group, key, QString(), flags, expand);
00744 }
00745 
00746 void KConfig::virtual_hook(int /*id*/, void* /*data*/)
00747 {
00748     /* nothing */
00749 }
00750 

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
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.6
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