kdecore Library: kconfig.cpp Source File (kdecore Library)

| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kconfig.cpp

    00001 /*
    00002   This file is part of the KDE libraries
    00003   Copyright (c) 1999 Preston Brown <pbrown@kde.org>
    00004   Copyright (C) 1997-1999 Matthias Kalle Dalheimer (kalle@kde.org)
    00005
    00006   This library is free software; you can redistribute it and/or
    00007   modify it under the terms of the GNU Library General Public
    00008   License as published by the Free Software Foundation; either
    00009   version 2 of the License, or (at your option) any later version.
    00010
    00011   This library is distributed in the hope that it will be useful,
    00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00014   Library General Public License for more details.
    00015
    00016   You should have received a copy of the GNU Library General Public License
    00017   along with this library; see the file COPYING.LIB.  If not, write to
    00018   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00019   Boston, MA 02111-1307, USA.
    00020 */
    00021
    00022 // $Id$
    00023
    00024 #include <config.h>
    00025
    00026 #ifdef HAVE_SYS_STAT_H
    00027 #include <sys/stat.h>
    00028 #endif
    00029
    00030 #include <stdlib.h>
    00031 #include <unistd.h>
    00032
    00033 #include <qfileinfo.h>
    00034
    00035 #include <kapplication.h>
    00036 #include "kconfigbackend.h"
    00037
    00038 #include "kconfig.h"
    00039 #include "kglobal.h"
    00040 #include "kstandarddirs.h"
    00041 #include "kstaticdeleter.h"
    00042 #include <qtimer.h>
    00043
    00044 KConfig::KConfig( const QString& fileName,
    00045                  bool bReadOnly, bool bUseKderc, const char *resType )
    00046   : KConfigBase(), bGroupImmutable(false), bFileImmutable(false),
    00047     bForceGlobal(false)
    00048 {
    00049   // set the object's read-only status.
    00050   setReadOnly(bReadOnly);
    00051
    00052   // for right now we will hardcode that we are using the INI
    00053   // back end driver.  In the future this should be converted over to
    00054   // a object factory of some sorts.
    00055   KConfigINIBackEnd *aBackEnd = new KConfigINIBackEnd(this,
    00056                               fileName,
    00057                                                       resType,
    00058                               bUseKderc);
    00059
    00060   // set the object's back end pointer to this new backend
    00061   backEnd = aBackEnd;
    00062
    00063   // read initial information off disk
    00064   reparseConfiguration();
    00065
    00066   // we let KStandardDirs add custom user config files. It will do
    00067   // this only once. So only the first call ever to this constructor
    00068   // will anything else than return here We have to reparse here as
    00069   // configuration files may appear after customized directories have
    00070   // been added. and the info they contain needs to be inserted into the
    00071   // config object.
    00072   // Since this makes only sense for config directories, addCustomized
    00073   // returns true only if new config directories appeared.
    00074   if (KGlobal::dirs()->addCustomized(this))
    00075       reparseConfiguration();
    00076 }
    00077
    00078 KConfig::KConfig(KConfigBackEnd *aBackEnd, bool bReadOnly)
    00079     : bGroupImmutable(false), bFileImmutable(false),
    00080     bForceGlobal(false)
    00081 {
    00082   setReadOnly(bReadOnly);
    00083   backEnd = aBackEnd;
    00084   reparseConfiguration();
    00085 }
    00086
    00087 KConfig::~KConfig()
    00088 {
    00089   sync();
    00090
    00091   delete backEnd;
    00092 }
    00093
    00094 void KConfig::rollback(bool bDeep)
    00095 {
    00096   KConfigBase::rollback(bDeep);
    00097
    00098   if (!bDeep)
    00099     return; // object's bDeep flag is set in KConfigBase method
    00100
    00101   // clear any dirty flags that entries might have set
    00102   for (KEntryMapIterator aIt = aEntryMap.begin();
    00103        aIt != aEntryMap.end(); ++aIt)
    00104     (*aIt).bDirty = false;
    00105 }
    00106
    00107 QStringList KConfig::groupList() const
    00108 {
    00109   QStringList retList;
    00110
    00111   KEntryMapConstIterator aIt = aEntryMap.begin();
    00112   KEntryMapConstIterator aEnd = aEntryMap.end();
    00113   for (; aIt != aEnd; ++aIt)
    00114   {
    00115     while(aIt.key().mKey.isEmpty())
    00116     {
    00117       QCString group = aIt.key().mGroup;
    00118       ++aIt;
    00119       while (true)
    00120       {
    00121          if (aIt == aEnd)
    00122             return retList; // done
    00123
    00124          if (aIt.key().mKey.isEmpty())
    00125             break; // Group is empty, next group
    00126
    00127          if (!aIt.key().bDefault && !(*aIt).bDeleted)
    00128          {
    00129             if (group != "$Version") // Special case!
    00130                retList.append(QString::fromUtf8(group));
    00131             break; // Group is non-empty, added, next group
    00132          }
    00133          ++aIt;
    00134       }
    00135     }
    00136   }
    00137
    00138   return retList;
    00139 }
    00140
    00141 QMap<QString, QString> KConfig::entryMap(const QString &pGroup) const
    00142 {
    00143   QCString pGroup_utf = pGroup.utf8();
    00144   KEntryKey groupKey( pGroup_utf, 0 );
    00145   QMap<QString, QString> tmpMap;
    00146
    00147   KEntryMapConstIterator aIt = aEntryMap.find(groupKey);
    00148   if (aIt == aEntryMap.end())
    00149      return tmpMap;
    00150   ++aIt; // advance past special group entry marker
    00151   for (; aIt.key().mGroup == pGroup_utf && aIt != aEntryMap.end(); ++aIt)
    00152   {
    00153     // Leave the default values out && leave deleted entries out
    00154     if (!aIt.key().bDefault && !(*aIt).bDeleted)
    00155       tmpMap.insert(QString::fromUtf8(aIt.key().mKey), QString::fromUtf8((*aIt).mValue.data(), (*aIt).mValue.length()));
    00156   }
    00157
    00158   return tmpMap;
    00159 }
    00160
    00161 void KConfig::reparseConfiguration()
    00162 {
    00163   // Don't lose pending changes
    00164   if (!isReadOnly() && backEnd && bDirty)
    00165     backEnd->sync();
    00166
    00167   aEntryMap.clear();
    00168
    00169   // add the "default group" marker to the map
    00170   KEntryKey groupKey("<default>", 0);
    00171   aEntryMap.insert(groupKey, KEntry());
    00172
    00173   bFileImmutable = false;
    00174   parseConfigFiles();
    00175   bFileImmutable = bReadOnly;
    00176 }
    00177
    00178 KEntryMap KConfig::internalEntryMap(const QString &pGroup) const
    00179 {
    00180   QCString pGroup_utf = pGroup.utf8();
    00181   KEntry aEntry;
    00182   KEntryMapConstIterator aIt;
    00183   KEntryKey aKey(pGroup_utf, 0);
    00184   KEntryMap tmpEntryMap;
    00185
    00186   aIt = aEntryMap.find(aKey);
    00187   if (aIt == aEntryMap.end()) {
    00188     // the special group key is not in the map,
    00189     // so it must be an invalid group.  Return
    00190     // an empty map.
    00191     return tmpEntryMap;
    00192   }
    00193   // we now have a pointer to the nodes we want to copy.
    00194   for (; aIt.key().mGroup == pGroup_utf && aIt != aEntryMap.end(); ++aIt)
    00195   {
    00196     tmpEntryMap.insert(aIt.key(), *aIt);
    00197   }
    00198
    00199   return tmpEntryMap;
    00200 }
    00201
    00202 void KConfig::putData(const KEntryKey &_key, const KEntry &_data, bool _checkGroup)
    00203 {
    00204   if (bFileImmutable && !_key.bDefault)
    00205     return;
    00206
    00207   // check to see if the special group key is present,
    00208   // and if not, put it in.
    00209   if (_checkGroup)
    00210   {
    00211     KEntryKey groupKey( _key.mGroup, 0);
    00212     KEntry &entry = aEntryMap[groupKey];
    00213     bGroupImmutable = entry.bImmutable;
    00214   }
    00215   if (bGroupImmutable && !_key.bDefault)
    00216     return;
    00217
    00218   // now either add or replace the data
    00219   KEntry &entry = aEntryMap[_key];
    00220   bool immutable = entry.bImmutable;
    00221   if (immutable && !_key.bDefault)
    00222     return;
    00223
    00224   entry = _data;
    00225   entry.bImmutable |= immutable;
    00226   entry.bGlobal |= bForceGlobal; // force to kdeglobals
    00227
    00228   if (_key.bDefault)
    00229   {
    00230      // We have added the data as default value,
    00231      // add it as normal value as well.
    00232      KEntryKey key(_key);
    00233      key.bDefault = false;
    00234      aEntryMap[key] = _data;
    00235   }
    00236 }
    00237
    00238 KEntry KConfig::lookupData(const KEntryKey &_key) const
    00239 {
    00240   KEntryMapConstIterator aIt = aEntryMap.find(_key);
    00241   if (aIt != aEntryMap.end())
    00242   {
    00243     const KEntry &entry = *aIt;
    00244     if (entry.bDeleted)
    00245        return KEntry();
    00246     else
    00247        return entry;
    00248   }
    00249   else {
    00250     return KEntry();
    00251   }
    00252 }
    00253
    00254 bool KConfig::internalHasGroup(const QCString &group) const
    00255 {
    00256   KEntryKey groupKey( group, 0);
    00257
    00258   KEntryMapConstIterator aIt = aEntryMap.find(groupKey);
    00259   KEntryMapConstIterator aEnd = aEntryMap.end();
    00260
    00261   if (aIt == aEnd)
    00262      return false;
    00263   ++aIt;
    00264   for(; (aIt != aEnd); ++aIt)
    00265   {
    00266      if (aIt.key().mKey.isEmpty())
    00267         break;
    00268
    00269      if (!aIt.key().bDefault && !(*aIt).bDeleted)
    00270         return true;
    00271   }
    00272   return false;
    00273 }
    00274
    00275 void KConfig::setFileWriteMode(int mode)
    00276 {
    00277   backEnd->setFileWriteMode(mode);
    00278 }
    00279
    00280 KLockFile::Ptr KConfig::lockFile(bool bGlobal)
    00281 {
    00282   KConfigINIBackEnd *aBackEnd = dynamic_cast<KConfigINIBackEnd*>(backEnd);
    00283   if (!aBackEnd) return 0;
    00284   return aBackEnd->lockFile(bGlobal);
    00285 }
    00286
    00287 void KConfig::checkUpdate(const QString &id, const QString &updateFile)
    00288 {
    00289   QString oldGroup = group();
    00290   setGroup("$Version");
    00291   QString cfg_id = updateFile+":"+id;
    00292   QStringList ids = readListEntry("update_info");
    00293   if (!ids.contains(cfg_id))
    00294   {
    00295      QStringList args;
    00296      args << "--check" << updateFile;
    00297      KApplication::kdeinitExecWait("kconf_update", args);
    00298      reparseConfiguration();
    00299   }
    00300   setGroup(oldGroup);
    00301 }
    00302
    00303 KConfig* KConfig::copyTo(const QString &file, KConfig *config) const
    00304 {
    00305   if (!config)
    00306      config = new KConfig(QString::null, false, false);
    00307   config->backEnd->changeFileName(file, "config", false);
    00308   config->setReadOnly(false);
    00309   config->bFileImmutable = false;
    00310   config->backEnd->mConfigState = ReadWrite;
    00311
    00312   QStringList groups = groupList();
    00313   for(QStringList::ConstIterator it = groups.begin();
    00314       it != groups.end(); ++it)
    00315   {
    00316      QMap<QString, QString> map = entryMap(*it);
    00317      config->setGroup(*it);
    00318      for (QMap<QString,QString>::Iterator it2  = map.begin();
    00319           it2 != map.end(); ++it2)
    00320      {
    00321         config->writeEntry(it2.key(), it2.data());
    00322      }
    00323
    00324   }
    00325   return config;
    00326 }
    00327
    00328 void KConfig::virtual_hook( int id, void* data )
    00329 { KConfigBase::virtual_hook( id, data ); }
    00330
    00331 static KStaticDeleter< QValueList<KSharedConfig*> > sd;
    00332 QValueList<KSharedConfig*> *KSharedConfig::s_list = 0;
    00333
    00334 KSharedConfig::Ptr KSharedConfig::openConfig(const QString& fileName, bool immutable, bool useKDEGlobals )
    00335 {
    00336   if (s_list)
    00337   {
    00338      for(QValueList<KSharedConfig*>::ConstIterator it = s_list->begin();
    00339          it != s_list->end(); ++it)
    00340      {
    00341         if ((*it)->backEnd->fileName() == fileName &&
    00342                 (*it)->backEnd->bFileImmutable == immutable &&
    00343                 (*it)->backEnd->useKDEGlobals == useKDEGlobals )
    00344            return (*it);
    00345      }
    00346   }
    00347   return new KSharedConfig(fileName, immutable, useKDEGlobals);
    00348 }
    00349
    00350 KSharedConfig::KSharedConfig( const QString& fileName, bool readonly, bool usekdeglobals)
    00351  : KConfig(fileName, readonly, usekdeglobals)
    00352 {
    00353   if (!s_list)
    00354   {
    00355     sd.setObject(s_list, new QValueList<KSharedConfig*>);
    00356   }
    00357
    00358   s_list->append(this);
    00359 }
    00360
    00361 KSharedConfig::~KSharedConfig()
    00362 {
    00363   if ( s_list )
    00364     s_list->remove(this);
    00365 }
    00366
    00367 #include "kconfig.moc"

This file is part of the documentation for kdecore Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:18:02 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003