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