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 Fri Aug 20 09:48:25 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003