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

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.4
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