42 #include <qbytearray.h>
45 #include <qdatetime.h>
49 #include <QtCore/QProcess>
50 #include <QtCore/QPointer>
51 #include <QtCore/QSet>
52 #include <QtCore/QStack>
54 bool KConfigPrivate::mappingsRegistered=
false;
58 : openFlags(flags), resourceType(resource), mBackend(0),
59 bDynamicBackend(true), bDirty(false), bReadDefaults(false),
60 bFileImmutable(false), bForceGlobal(false), bSuppressGlobal(false),
61 componentData(componentData_), configState(
KConfigBase::NoAccess)
65 static int use_etc_kderc = -1;
66 if (use_etc_kderc < 0)
67 use_etc_kderc = getenv(
"KDE_SKIP_KDERC") != 0 ? 0 : 1;
72 QFile::decodeName( qgetenv(
"WINDIR") +
"/kde4rc" );
74 QLatin1String(
"/etc/kde4rc");
100 bool KConfigPrivate::lockLocal()
110 KConfigGroup *otherGroup, KConfigBase::WriteConfigFlags flags)
const
113 const int len = source.length();
114 const bool sameName = (destination == source);
119 bool dirtied =
false;
121 for (KEntryMap::ConstIterator entryMapIt( entryMap.constBegin() ); entryMapIt != entryMap.constEnd(); ++entryMapIt) {
122 const QByteArray&
group = entryMapIt.key().mGroup;
124 if (!group.startsWith(source))
128 if (group.length() > len && group[len] !=
'\x1d')
138 newKey.
mGroup.replace(0, len, destination);
140 KEntry entry = entryMap[ entryMapIt.key() ];
147 otherMap[newKey] = entry;
160 int nDollarPos = aValue.indexOf( QLatin1Char(
'$') );
161 while( nDollarPos != -1 && nDollarPos+1 < aValue.length()) {
163 if( aValue[nDollarPos+1] == QLatin1Char(
'(') ) {
164 int nEndPos = nDollarPos+1;
166 while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!=QLatin1Char(
')')) )
169 QString cmd = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 );
172 QByteArray oldpath = qgetenv(
"PATH" );
175 newpath = QFile::encodeName(
KGlobal::dirs()->resourceDirs(
"exe").join(QChar::fromLatin1(KPATH_SEPARATOR)));
176 if (!newpath.isEmpty() && !oldpath.isEmpty())
177 newpath += KPATH_SEPARATOR;
180 setenv(
"PATH", newpath, 1 );
183 FILE *fs = popen(QFile::encodeName(cmd).data(),
"r");
185 QTextStream ts(fs, QIODevice::ReadOnly);
186 result = ts.readAll().trimmed();
190 setenv(
"PATH", oldpath, 1 );
191 aValue.replace( nDollarPos, nEndPos-nDollarPos, result );
192 nDollarPos += result.length();
193 }
else if( aValue[nDollarPos+1] != QLatin1Char(
'$') ) {
194 int nEndPos = nDollarPos+1;
197 if ( aValue[nEndPos] == QLatin1Char(
'{') ) {
198 while ( (nEndPos <= aValue.length()) && (aValue[nEndPos] != QLatin1Char(
'}')) )
201 aVarName = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 );
203 while ( nEndPos <= aValue.length() &&
204 (aValue[nEndPos].isNumber() ||
205 aValue[nEndPos].isLetter() ||
206 aValue[nEndPos] == QLatin1Char(
'_') ) )
208 aVarName = aValue.mid( nDollarPos+1, nEndPos-nDollarPos-1 );
211 if (!aVarName.isEmpty()) {
213 if (aVarName == QLatin1String(
"HOME"))
214 env = QDir::homePath();
218 QByteArray pEnv = qgetenv( aVarName.toLatin1() );
219 if( !pEnv.isEmpty() )
225 aValue.replace(nDollarPos, nEndPos-nDollarPos, env);
226 nDollarPos += env.length();
228 aValue.remove( nDollarPos, nEndPos-nDollarPos );
231 aValue.remove( nDollarPos, 1 );
234 nDollarPos = aValue.indexOf( QLatin1Char(
'$'), nDollarPos );
242 const char* resourceType)
252 const char* resourceType)
280 if (d->bDirty && d->mBackend.isUnique())
288 return d->componentData;
294 QSet<QString> groups;
296 for (KEntryMap::ConstIterator entryMapIt( d->entryMap.constBegin() ); entryMapIt != d->entryMap.constEnd(); ++entryMapIt) {
299 if (key.
mKey.isNull() && !group.isEmpty() && group !=
"<default>" && group !=
"$Version") {
300 const QString groupname = QString::fromUtf8(group);
301 groups << groupname.left(groupname.indexOf(QLatin1Char(
'\x1d')));
305 return groups.toList();
310 QByteArray theGroup = group +
'\x1d';
311 QSet<QString> groups;
313 for (KEntryMap::ConstIterator entryMapIt( entryMap.constBegin() ); entryMapIt != entryMap.constEnd(); ++entryMapIt) {
315 if (key.
mKey.isNull() && key.
mGroup.startsWith(theGroup)) {
316 const QString groupname = QString::fromUtf8(key.
mGroup.mid(theGroup.length()));
317 groups << groupname.left(groupname.indexOf(QLatin1Char(
'\x1d')));
321 return groups.toList();
327 QSet<QByteArray> groups;
328 QByteArray theGroup = parentGroup +
'\x1d';
329 groups << parentGroup;
331 for (KEntryMap::const_iterator entryMapIt = entryMap.begin(); entryMapIt != entryMap.end(); ++entryMapIt) {
333 if (key.
mKey.isNull() && key.
mGroup.startsWith(theGroup)) {
344 Q_FOREACH(
const QByteArray& aGroup, allGroups) {
358 const KEntryMapConstIterator theEnd = entryMap.constEnd();
359 KEntryMapConstIterator it = entryMap.
findEntry(theGroup);
364 for (; it != theEnd && it.key().mGroup == theGroup; ++it) {
366 if (key.
mGroup == theGroup && !key.
mKey.isNull() && !it->bDeleted)
367 tmp << QString::fromUtf8(key.
mKey);
378 const QByteArray theGroup(aGroup.isEmpty() ?
"<default>" : aGroup.toUtf8());
379 return d->keyListImpl(theGroup);
386 const QByteArray theGroup(aGroup.isEmpty() ?
"<default>" : aGroup.toUtf8());
388 const KEntryMapConstIterator theEnd = d->entryMap.constEnd();
389 KEntryMapConstIterator it = d->entryMap.findEntry(theGroup, 0, 0);
393 for (; it != theEnd && it.key().mGroup == theGroup; ++it) {
395 if (!it->bDeleted && !it.key().bDefault) {
396 const QString key = QString::fromUtf8(it.key().mKey.constData());
399 if (!theMap.contains(key)) {
403 theMap.insert(key,QString::fromUtf8(it->mValue.constData()));
423 if (d->bDirty && d->mBackend) {
424 const QByteArray utf8Locale(
locale().toUtf8());
427 d->mBackend->createEnclosing();
430 if (d->configState ==
ReadWrite && !d->lockLocal()) {
431 qWarning() <<
"couldn't lock local file";
436 bool writeGlobals =
false;
437 bool writeLocals =
false;
438 foreach (
const KEntry& e, d->entryMap) {
446 if (writeGlobals && writeLocals) {
454 if (d->wantGlobals() && writeGlobals) {
457 qWarning() <<
"couldn't lock global file";
472 if (!d->mBackend->writeConfig(utf8Locale, d->entryMap, KConfigBackend::WriteOptions(), d->componentData)) {
478 if (d->mBackend->isLocked()) {
479 d->mBackend->unlock();
490 const KEntryMapIterator theEnd = d->entryMap.end();
491 for (KEntryMapIterator it = d->entryMap.begin(); it != theEnd; ++it)
498 const QString cfg_id = updateFile+QLatin1Char(
':')+id;
500 if (!ids.contains(cfg_id)) {
511 config->d_func()->changeFileName(file, d->resourceType);
512 config->d_func()->
entryMap = d->entryMap;
513 config->d_func()->bFileImmutable =
false;
515 const KEntryMapIterator theEnd = config->d_func()->
entryMap.end();
516 for (KEntryMapIterator it = config->d_func()->
entryMap.begin(); it != theEnd; ++it)
518 config->
d_ptr->bDirty =
true;
534 if (name.isEmpty()) {
535 if (wantDefaults()) {
537 if (!appName.isEmpty()) {
538 fileName = appName + QLatin1String(
"rc");
543 }
else if (wantGlobals()) {
545 fileName = QLatin1String(
"kdeglobals");
546 file = sGlobalFileName;
549 }
else if (QDir::isAbsolutePath(fileName)) {
558 if (file.isEmpty()) {
563 bSuppressGlobal = (file == sGlobalFileName);
576 if (d->fileName.isEmpty()) {
581 if (!d->isReadOnly() && d->bDirty)
586 d->bFileImmutable =
false;
589 if (d->wantGlobals())
590 d->parseGlobalFiles();
592 d->parseConfigFiles();
601 globalFiles.push_front(dir1);
603 globalFiles.push_front(dir2);
604 if (!etc_kderc.isEmpty())
605 globalFiles.push_front(etc_kderc);
609 void KConfigPrivate::parseGlobalFiles()
616 const QByteArray utf8Locale = locale.toUtf8();
617 foreach(
const QString& file, globalFiles) {
619 if (file != sGlobalFileName)
628 void KConfigPrivate::parseConfigFiles()
631 if (
mBackend && !fileName.isEmpty()) {
633 bFileImmutable =
false;
635 QList<QString> files;
636 if (wantDefaults()) {
637 if (bSuppressGlobal) {
638 files = getGlobalFiles();
648 files = extraFiles.toList() + files;
652 const QByteArray utf8Locale = locale.toUtf8();
653 foreach(
const QString& file, files) {
659 bFileImmutable =
true;
667 bFileImmutable = (backend->
parseConfig(utf8Locale, entryMap,
676 bFileImmutable =
true;
683 return d->configState;
689 foreach(
const QString& file, files) {
690 d->extraFiles.push(file);
693 if (!files.isEmpty()) {
704 bool KConfigPrivate::setLocale(
const QString& aLocale)
706 if (aLocale != locale) {
716 if (d->setLocale(locale)) {
726 d->bReadDefaults = b;
732 return d->bReadDefaults;
738 return d->bFileImmutable;
747 #ifndef KDE_NO_DEPRECATED
755 #ifndef KDE_NO_DEPRECATED
759 return d->bForceGlobal;
775 KEntryMap::EntryOptions options=0;
791 const QSet<QByteArray> groups = d->allSubGroups(aGroup);
792 foreach (
const QByteArray&
group, groups) {
794 foreach (
const QString& _key, keys) {
795 const QByteArray &key = _key.toUtf8();
796 if (d->canWriteEntry(group, key.constData())) {
797 d->entryMap.setEntry(group, key, QByteArray(), options);
807 bool allWritable = (d->mBackend.isNull()?
false: d->mBackend->isWritable());
809 if (warnUser && !allWritable) {
811 if (!d->mBackend.isNull())
812 errorMsg = d->mBackend->nonWritableErrorMessage();
815 errorMsg +=
i18n(
"Please contact your system administrator.");
820 << QString::fromLatin1(
"--title") <<
componentData().componentName()
821 << QString::fromLatin1(
"--msgbox") << errorMsg);
837 return d->hasNonDeletedEntries(aGroup);
842 if (bFileImmutable ||
849 const QByteArray& value, KConfigBase::WriteConfigFlags flags,
bool expand)
861 bool dirtied = entryMap.
setEntry(group, key, value, options);
867 KEntryMap::SearchFlags flags)
const
871 const KEntryMapConstIterator it = entryMap.
findEntry(group, key, flags);
872 if (it == entryMap.constEnd())
878 KEntryMap::SearchFlags flags,
bool *expand)
const