kdecore Library API Documentation

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: kconfig.cpp,v 1.79.2.1 2004/05/21 21:05:08 waba Exp $
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 <qtimer.h>
00042 
00043 KConfig::KConfig( const QString& fileName,
00044                  bool bReadOnly, bool bUseKderc, const char *resType )
00045   : KConfigBase(), bGroupImmutable(false), bFileImmutable(false),
00046     bForceGlobal(false)
00047 {
00048   // set the object's read-only status.
00049   setReadOnly(bReadOnly);
00050 
00051   // for right now we will hardcode that we are using the INI
00052   // back end driver.  In the future this should be converted over to
00053   // a object factory of some sorts.
00054   KConfigINIBackEnd *aBackEnd = new KConfigINIBackEnd(this,
00055                               fileName,
00056                                                       resType,
00057                               bUseKderc);
00058 
00059   // set the object's back end pointer to this new backend
00060   backEnd = aBackEnd;
00061 
00062   // read initial information off disk
00063   reparseConfiguration();
00064 
00065   // we let KStandardDirs add custom user config files. It will do
00066   // this only once. So only the first call ever to this constructor
00067   // will anything else than return here We have to reparse here as
00068   // configuration files may appear after customized directories have
00069   // been added. and the info they contain needs to be inserted into the
00070   // config object.
00071   // Since this makes only sense for config directories, addCustomized
00072   // returns true only if new config directories appeared.
00073   if (KGlobal::dirs()->addCustomized(this))
00074       reparseConfiguration();
00075 }
00076 
00077 KConfig::KConfig(KConfigBackEnd *aBackEnd, bool bReadOnly)
00078     : bGroupImmutable(false), bFileImmutable(false),
00079     bForceGlobal(false)
00080 {
00081   setReadOnly(bReadOnly);
00082   backEnd = aBackEnd;
00083   reparseConfiguration();
00084 }
00085 
00086 KConfig::~KConfig()
00087 {
00088   sync();
00089 
00090   delete backEnd;
00091 }
00092 
00093 void KConfig::rollback(bool bDeep)
00094 {
00095   KConfigBase::rollback(bDeep);
00096 
00097   if (!bDeep)
00098     return; // object's bDeep flag is set in KConfigBase method
00099 
00100   // clear any dirty flags that entries might have set
00101   for (KEntryMapIterator aIt = aEntryMap.begin();
00102        aIt != aEntryMap.end(); ++aIt)
00103     (*aIt).bDirty = false;
00104 }
00105 
00106 QStringList KConfig::groupList() const
00107 {
00108   QStringList retList;
00109 
00110   KEntryMapConstIterator aIt = aEntryMap.begin();
00111   KEntryMapConstIterator aEnd = aEntryMap.end();
00112   for (; aIt != aEnd; ++aIt)
00113   {
00114     while(aIt.key().mKey.isEmpty())
00115     {
00116       QCString group = aIt.key().mGroup;
00117       ++aIt;
00118       while (true)
00119       {
00120          if (aIt == aEnd)
00121             return retList; // done
00122 
00123          if (aIt.key().mKey.isEmpty())
00124             break; // Group is empty, next group
00125 
00126          if (!aIt.key().bDefault && !(*aIt).bDeleted)
00127          {
00128             if (group != "$Version") // Special case!
00129                retList.append(QString::fromUtf8(group));
00130             break; // Grou is non-empty, added, next gropup
00131          }
00132          ++aIt;
00133       }
00134     }
00135   }
00136 
00137   return retList;
00138 }
00139 
00140 QMap<QString, QString> KConfig::entryMap(const QString &pGroup) const
00141 {
00142   QCString pGroup_utf = pGroup.utf8();
00143   KEntryKey groupKey( pGroup_utf, 0 );
00144   QMap<QString, QString> tmpMap;
00145 
00146   KEntryMapConstIterator aIt = aEntryMap.find(groupKey);
00147   if (aIt == aEntryMap.end())
00148      return tmpMap;
00149   ++aIt; // advance past special group entry marker
00150   for (; aIt.key().mGroup == pGroup_utf && aIt != aEntryMap.end(); ++aIt)
00151   {
00152     // Leave the default values out && leave deleted entries out
00153     if (!aIt.key().bDefault && !(*aIt).bDeleted)
00154       tmpMap.insert(QString::fromUtf8(aIt.key().mKey), QString::fromUtf8((*aIt).mValue.data(), (*aIt).mValue.length()));
00155   }
00156 
00157   return tmpMap;
00158 }
00159 
00160 void KConfig::reparseConfiguration()
00161 {
00162   // Don't lose pending changes
00163   if (!isReadOnly() && backEnd && bDirty)
00164     backEnd->sync();
00165 
00166   aEntryMap.clear();
00167 
00168   // add the "default group" marker to the map
00169   KEntryKey groupKey("<default>", 0);
00170   aEntryMap.insert(groupKey, KEntry());
00171 
00172   bFileImmutable = false;
00173   parseConfigFiles();
00174   bFileImmutable = bReadOnly;
00175 }
00176 
00177 KEntryMap KConfig::internalEntryMap(const QString &pGroup) const
00178 {
00179   QCString pGroup_utf = pGroup.utf8();
00180   KEntry aEntry;
00181   KEntryMapConstIterator aIt;
00182   KEntryKey aKey(pGroup_utf, 0);
00183   KEntryMap tmpEntryMap;
00184 
00185   aIt = aEntryMap.find(aKey);
00186   if (aIt == aEntryMap.end()) {
00187     // the special group key is not in the map,
00188     // so it must be an invalid group.  Return
00189     // an empty map.
00190     return tmpEntryMap;
00191   }
00192   // we now have a pointer to the nodes we want to copy.
00193   for (; aIt.key().mGroup == pGroup_utf && aIt != aEntryMap.end(); ++aIt)
00194   {
00195     tmpEntryMap.insert(aIt.key(), *aIt);
00196   }
00197 
00198   return tmpEntryMap;
00199 }
00200 
00201 void KConfig::putData(const KEntryKey &_key, const KEntry &_data, bool _checkGroup)
00202 {
00203   if (bFileImmutable && !_key.bDefault)
00204     return;
00205 
00206   // check to see if the special group key is present,
00207   // and if not, put it in.
00208   if (_checkGroup)
00209   {
00210     KEntryKey groupKey( _key.mGroup, 0);
00211     KEntry &entry = aEntryMap[groupKey];
00212     bGroupImmutable = entry.bImmutable;
00213   }
00214   if (bGroupImmutable && !_key.bDefault)
00215     return;
00216 
00217   // now either add or replace the data
00218   KEntry &entry = aEntryMap[_key];
00219   bool immutable = entry.bImmutable;
00220   if (immutable && !_key.bDefault)
00221     return;
00222 
00223   entry = _data;
00224   entry.bImmutable |= immutable;
00225   entry.bGlobal |= bForceGlobal; // force to kdeglobals
00226 
00227   if (_key.bDefault)
00228   {
00229      // We have added the data as default value,
00230      // add it as normal value as well.
00231      KEntryKey key(_key);
00232      key.bDefault = false;
00233      aEntryMap[key] = _data;
00234   }
00235 }
00236 
00237 KEntry KConfig::lookupData(const KEntryKey &_key) const
00238 {
00239   KEntryMapConstIterator aIt = aEntryMap.find(_key);
00240   if (aIt != aEntryMap.end())
00241   {
00242     const KEntry &entry = *aIt;
00243     if (entry.bDeleted)
00244        return KEntry();
00245     else
00246        return entry;
00247   }
00248   else {
00249     return KEntry();
00250   }
00251 }
00252 
00253 bool KConfig::internalHasGroup(const QCString &group) const
00254 {
00255   KEntryKey groupKey( group, 0);
00256 
00257   KEntryMapConstIterator aIt = aEntryMap.find(groupKey);
00258   KEntryMapConstIterator aEnd = aEntryMap.end();
00259 
00260   if (aIt == aEnd)
00261      return false;
00262   ++aIt;
00263   for(; (aIt != aEnd); ++aIt)
00264   {
00265      if (aIt.key().mKey.isEmpty())
00266         break;
00267 
00268      if (!aIt.key().bDefault && !(*aIt).bDeleted)
00269         return true;
00270   }
00271   return false;
00272 }
00273 
00274 void KConfig::setFileWriteMode(int mode)
00275 {
00276   backEnd->setFileWriteMode(mode);
00277 }
00278 
00279 void KConfig::checkUpdate(const QString &id, const QString &updateFile)
00280 {
00281   QString oldGroup = group();
00282   setGroup("$Version");
00283   QString cfg_id = updateFile+":"+id;
00284   QStringList ids = readListEntry("update_info");
00285   if (!ids.contains(cfg_id))
00286   {
00287      QStringList args;
00288      args << "--check" << updateFile;
00289      KApplication::kdeinitExecWait("kconf_update", args);
00290      reparseConfiguration();
00291   }
00292   setGroup(oldGroup);
00293 }
00294 
00295 KConfig* KConfig::copyTo(const QString &file, KConfig *config) const
00296 {
00297   if (!config)
00298      config = new KConfig(QString::null, false, false);
00299   config->backEnd->changeFileName(file, "config", false);
00300   config->setReadOnly(false);
00301   config->bFileImmutable = false;
00302   config->backEnd->mConfigState = ReadWrite;
00303 
00304   QStringList groups = groupList();
00305   for(QStringList::ConstIterator it = groups.begin();
00306       it != groups.end(); ++it)
00307   {
00308      QMap<QString, QString> map = entryMap(*it);
00309      config->setGroup(*it);
00310      for (QMap<QString,QString>::Iterator it2  = map.begin();
00311           it2 != map.end(); ++it2)
00312      {
00313         config->writeEntry(it2.key(), it2.data());
00314      }
00315 
00316   }
00317   return config;
00318 }
00319 
00320 void KConfig::virtual_hook( int id, void* data )
00321 { KConfigBase::virtual_hook( id, data ); }
00322 
00323 QValueList<KSharedConfig*> *KSharedConfig::s_list = 0;
00324 
00325 KSharedConfig::Ptr KSharedConfig::openConfig(const QString& fileName, bool immutable, bool useKDEGlobals )
00326 {
00327   if (s_list)
00328   {
00329      for(QValueList<KSharedConfig*>::ConstIterator it = s_list->begin();
00330          it != s_list->end(); ++it)
00331      {
00332         if ((*it)->backEnd->fileName() == fileName)
00333            return (*it);
00334      }
00335   }
00336   return new KSharedConfig(fileName, immutable, useKDEGlobals);
00337 }
00338 
00339 KSharedConfig::KSharedConfig( const QString& fileName, bool readonly, bool usekdeglobals)
00340  : KConfig(fileName, readonly, usekdeglobals)
00341 {
00342   if (!s_list)
00343      s_list = new QValueList<KSharedConfig*>;
00344      
00345   s_list->append(this);
00346 }
00347 
00348 KSharedConfig::~KSharedConfig()
00349 {
00350   s_list->remove(this);
00351 }
00352 
00353 #include "kconfig.moc"
KDE Logo
This file is part of the documentation for kdecore Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 30 05:15:52 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2003