00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00050 setReadOnly(bReadOnly);
00051
00052
00053
00054
00055 KConfigINIBackEnd *aBackEnd = new KConfigINIBackEnd(this,
00056 fileName,
00057 resType,
00058 bUseKderc);
00059
00060
00061 backEnd = aBackEnd;
00062
00063 KGlobal::dirs()->addResourceDir( "config", "/etc/kde/config/");
00064
00065 reparseConfiguration();
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 if (KGlobal::dirs()->addCustomized(this))
00076 reparseConfiguration();
00077 }
00078
00079 KConfig::KConfig(KConfigBackEnd *aBackEnd, bool bReadOnly)
00080 : bGroupImmutable(false), bFileImmutable(false),
00081 bForceGlobal(false)
00082 {
00083 setReadOnly(bReadOnly);
00084 backEnd = aBackEnd;
00085 reparseConfiguration();
00086 }
00087
00088 KConfig::~KConfig()
00089 {
00090 sync();
00091
00092 delete backEnd;
00093 }
00094
00095 void KConfig::rollback(bool bDeep)
00096 {
00097 KConfigBase::rollback(bDeep);
00098
00099 if (!bDeep)
00100 return;
00101
00102
00103 for (KEntryMapIterator aIt = aEntryMap.begin();
00104 aIt != aEntryMap.end(); ++aIt)
00105 (*aIt).bDirty = false;
00106 }
00107
00108 QStringList KConfig::groupList() const
00109 {
00110 QStringList retList;
00111
00112 KEntryMapConstIterator aIt = aEntryMap.begin();
00113 KEntryMapConstIterator aEnd = aEntryMap.end();
00114 for (; aIt != aEnd; ++aIt)
00115 {
00116 while(aIt.key().mKey.isEmpty())
00117 {
00118 QCString group = aIt.key().mGroup;
00119 ++aIt;
00120 while (true)
00121 {
00122 if (aIt == aEnd)
00123 return retList;
00124
00125 if (aIt.key().mKey.isEmpty())
00126 break;
00127
00128 if (!aIt.key().bDefault && !(*aIt).bDeleted)
00129 {
00130 if (group != "$Version")
00131 retList.append(QString::fromUtf8(group));
00132 break;
00133 }
00134 ++aIt;
00135 }
00136 }
00137 }
00138
00139 return retList;
00140 }
00141
00142 QMap<QString, QString> KConfig::entryMap(const QString &pGroup) const
00143 {
00144 QCString pGroup_utf = pGroup.utf8();
00145 KEntryKey groupKey( pGroup_utf, 0 );
00146 QMap<QString, QString> tmpMap;
00147
00148 KEntryMapConstIterator aIt = aEntryMap.find(groupKey);
00149 if (aIt == aEntryMap.end())
00150 return tmpMap;
00151 ++aIt;
00152 for (; aIt.key().mGroup == pGroup_utf && aIt != aEntryMap.end(); ++aIt)
00153 {
00154
00155 if (!aIt.key().bDefault && !(*aIt).bDeleted)
00156 tmpMap.insert(QString::fromUtf8(aIt.key().mKey), QString::fromUtf8((*aIt).mValue.data(), (*aIt).mValue.length()));
00157 }
00158
00159 return tmpMap;
00160 }
00161
00162 void KConfig::reparseConfiguration()
00163 {
00164
00165 if (!isReadOnly() && backEnd && bDirty)
00166 backEnd->sync();
00167
00168 aEntryMap.clear();
00169
00170
00171 KEntryKey groupKey("<default>", 0);
00172 aEntryMap.insert(groupKey, KEntry());
00173
00174 bFileImmutable = false;
00175 parseConfigFiles();
00176 bFileImmutable = bReadOnly;
00177 }
00178
00179 KEntryMap KConfig::internalEntryMap(const QString &pGroup) const
00180 {
00181 QCString pGroup_utf = pGroup.utf8();
00182 KEntry aEntry;
00183 KEntryMapConstIterator aIt;
00184 KEntryKey aKey(pGroup_utf, 0);
00185 KEntryMap tmpEntryMap;
00186
00187 aIt = aEntryMap.find(aKey);
00188 if (aIt == aEntryMap.end()) {
00189
00190
00191
00192 return tmpEntryMap;
00193 }
00194
00195 for (; aIt.key().mGroup == pGroup_utf && aIt != aEntryMap.end(); ++aIt)
00196 {
00197 tmpEntryMap.insert(aIt.key(), *aIt);
00198 }
00199
00200 return tmpEntryMap;
00201 }
00202
00203 void KConfig::putData(const KEntryKey &_key, const KEntry &_data, bool _checkGroup)
00204 {
00205 if (bFileImmutable && !_key.bDefault)
00206 return;
00207
00208
00209
00210 if (_checkGroup)
00211 {
00212 KEntryKey groupKey( _key.mGroup, 0);
00213 KEntry &entry = aEntryMap[groupKey];
00214 bGroupImmutable = entry.bImmutable;
00215 }
00216 if (bGroupImmutable && !_key.bDefault)
00217 return;
00218
00219
00220 KEntry &entry = aEntryMap[_key];
00221 bool immutable = entry.bImmutable;
00222 if (immutable && !_key.bDefault)
00223 return;
00224
00225 entry = _data;
00226 entry.bImmutable |= immutable;
00227 entry.bGlobal |= bForceGlobal;
00228
00229 if (_key.bDefault)
00230 {
00231
00232
00233 KEntryKey key(_key);
00234 key.bDefault = false;
00235 aEntryMap[key] = _data;
00236 }
00237 }
00238
00239 KEntry KConfig::lookupData(const KEntryKey &_key) const
00240 {
00241 KEntryMapConstIterator aIt = aEntryMap.find(_key);
00242 if (aIt != aEntryMap.end())
00243 {
00244 const KEntry &entry = *aIt;
00245 if (entry.bDeleted)
00246 return KEntry();
00247 else
00248 return entry;
00249 }
00250 else {
00251 return KEntry();
00252 }
00253 }
00254
00255 bool KConfig::internalHasGroup(const QCString &group) const
00256 {
00257 KEntryKey groupKey( group, 0);
00258
00259 KEntryMapConstIterator aIt = aEntryMap.find(groupKey);
00260 KEntryMapConstIterator aEnd = aEntryMap.end();
00261
00262 if (aIt == aEnd)
00263 return false;
00264 ++aIt;
00265 for(; (aIt != aEnd); ++aIt)
00266 {
00267 if (aIt.key().mKey.isEmpty())
00268 break;
00269
00270 if (!aIt.key().bDefault && !(*aIt).bDeleted)
00271 return true;
00272 }
00273 return false;
00274 }
00275
00276 void KConfig::setFileWriteMode(int mode)
00277 {
00278 backEnd->setFileWriteMode(mode);
00279 }
00280
00281 KLockFile::Ptr KConfig::lockFile(bool bGlobal)
00282 {
00283 KConfigINIBackEnd *aBackEnd = dynamic_cast<KConfigINIBackEnd*>(backEnd);
00284 if (!aBackEnd) return 0;
00285 return aBackEnd->lockFile(bGlobal);
00286 }
00287
00288 void KConfig::checkUpdate(const QString &id, const QString &updateFile)
00289 {
00290 QString oldGroup = group();
00291 setGroup("$Version");
00292 QString cfg_id = updateFile+":"+id;
00293 QStringList ids = readListEntry("update_info");
00294 if (!ids.contains(cfg_id))
00295 {
00296 QStringList args;
00297 args << "--check" << updateFile;
00298 KApplication::kdeinitExecWait("kconf_update", args);
00299 reparseConfiguration();
00300 }
00301 setGroup(oldGroup);
00302 }
00303
00304 KConfig* KConfig::copyTo(const QString &file, KConfig *config) const
00305 {
00306 if (!config)
00307 config = new KConfig(QString::null, false, false);
00308 config->backEnd->changeFileName(file, "config", false);
00309 config->setReadOnly(false);
00310 config->bFileImmutable = false;
00311 config->backEnd->mConfigState = ReadWrite;
00312
00313 QStringList groups = groupList();
00314 for(QStringList::ConstIterator it = groups.begin();
00315 it != groups.end(); ++it)
00316 {
00317 QMap<QString, QString> map = entryMap(*it);
00318 config->setGroup(*it);
00319 for (QMap<QString,QString>::Iterator it2 = map.begin();
00320 it2 != map.end(); ++it2)
00321 {
00322 config->writeEntry(it2.key(), it2.data());
00323 }
00324
00325 }
00326 return config;
00327 }
00328
00329 void KConfig::virtual_hook( int id, void* data )
00330 { KConfigBase::virtual_hook( id, data ); }
00331
00332 static KStaticDeleter< QValueList<KSharedConfig*> > sd;
00333 QValueList<KSharedConfig*> *KSharedConfig::s_list = 0;
00334
00335 KSharedConfig::Ptr KSharedConfig::openConfig(const QString& fileName, bool readOnly, bool useKDEGlobals )
00336 {
00337 if (s_list)
00338 {
00339 for(QValueList<KSharedConfig*>::ConstIterator it = s_list->begin();
00340 it != s_list->end(); ++it)
00341 {
00342 if ((*it)->backEnd->fileName() == fileName &&
00343 (*it)->bReadOnly == readOnly &&
00344 (*it)->backEnd->useKDEGlobals == useKDEGlobals )
00345 return (*it);
00346 }
00347 }
00348 return new KSharedConfig(fileName, readOnly, useKDEGlobals);
00349 }
00350
00351 KSharedConfig::KSharedConfig( const QString& fileName, bool readonly, bool usekdeglobals)
00352 : KConfig(fileName, readonly, usekdeglobals)
00353 {
00354 if (!s_list)
00355 {
00356 sd.setObject(s_list, new QValueList<KSharedConfig*>);
00357 }
00358
00359 s_list->append(this);
00360 }
00361
00362 KSharedConfig::~KSharedConfig()
00363 {
00364 if ( s_list )
00365 s_list->remove(this);
00366 }
00367
00368 #include "kconfig.moc"