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.85 2004/05/21 20:51:18 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 "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"
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:26:06 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003