KDECore
kconfiggroup.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the KDE libraries 00003 Copyright (c) 2006, 2007 Thomas Braxton <kde.braxton@gmail.com> 00004 Copyright (c) 1999 Preston Brown <pbrown@kde.org> 00005 Copyright (c) 1997 Matthias Kalle Dalheimer <kalle@kde.org> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #include "kconfiggroup.h" 00024 #include "kconfiggroup_p.h" 00025 00026 #include <config.h> 00027 00028 #include "kconfig.h" 00029 #include "kconfig_p.h" 00030 #include "ksharedconfig.h" 00031 #include "kstringhandler.h" 00032 #include "kcomponentdata.h" 00033 #include "kstandarddirs.h" 00034 #include "kconfigdata.h" 00035 #include "kde_file.h" 00036 #include <kdebug.h> 00037 00038 #include <QtCore/QDate> 00039 #include <QtCore/QSharedData> 00040 #include <QtCore/QFile> 00041 #include <QtCore/QPoint> 00042 #include <QtCore/QRect> 00043 #include <QtCore/QString> 00044 #include <QtCore/QTextStream> 00045 #include <QtCore/QDir> 00046 00047 #include <stdlib.h> 00048 00049 class KConfigGroupPrivate : public QSharedData 00050 { 00051 public: 00052 KConfigGroupPrivate(KConfig* owner, bool isImmutable, bool isConst, const QByteArray &name) 00053 : mOwner(owner), mName(name), bImmutable(isImmutable), bConst(isConst) 00054 { 00055 } 00056 00057 KConfigGroupPrivate(const KSharedConfigPtr &owner, const QByteArray& name) 00058 : sOwner(owner), mOwner(sOwner.data()), mName(name), 00059 bImmutable(name.isEmpty()? owner->isImmutable(): owner->isGroupImmutable(name)), bConst(false) 00060 { 00061 } 00062 00063 KConfigGroupPrivate(KConfigGroup* parent, bool isImmutable, bool isConst, const QByteArray& name) 00064 : sOwner(parent->d->sOwner), mOwner(parent->d->mOwner), mName(name), 00065 bImmutable(isImmutable), bConst(isConst) 00066 { 00067 if (!parent->d->mName.isEmpty()) 00068 mParent = parent->d; 00069 } 00070 00071 KConfigGroupPrivate(const KConfigGroupPrivate* other, bool isImmutable, const QByteArray &name) 00072 : sOwner(other->sOwner), mOwner(other->mOwner), mName(name), 00073 bImmutable(isImmutable), bConst(other->bConst) 00074 { 00075 if (!other->mName.isEmpty()) 00076 mParent = const_cast<KConfigGroupPrivate *>(other); 00077 } 00078 00079 KSharedConfig::Ptr sOwner; 00080 KConfig *mOwner; 00081 QExplicitlySharedDataPointer<KConfigGroupPrivate> mParent; 00082 QByteArray mName; 00083 00084 /* bitfield */ 00085 const bool bImmutable:1; // is this group immutable? 00086 const bool bConst:1; // is this group read-only? 00087 00088 QByteArray fullName() const 00089 { 00090 if (!mParent) { 00091 return name(); 00092 } 00093 return mParent->fullName(mName); 00094 } 00095 00096 QByteArray name() const 00097 { 00098 if (mName.isEmpty()) 00099 return "<default>"; 00100 return mName; 00101 } 00102 00103 QByteArray fullName(const QByteArray& aGroup) const 00104 { 00105 if (mName.isEmpty()) 00106 return aGroup; 00107 return fullName() + '\x1d' + aGroup; 00108 } 00109 00110 static QString expandString(const QString& value); 00111 00112 static QExplicitlySharedDataPointer<KConfigGroupPrivate> create(KConfigBase *master, 00113 const QByteArray &name, 00114 bool isImmutable, 00115 bool isConst) 00116 { 00117 QExplicitlySharedDataPointer<KConfigGroupPrivate> data; 00118 if (dynamic_cast<KConfigGroup*>(master)) 00119 data = new KConfigGroupPrivate(dynamic_cast<KConfigGroup*>(master), isImmutable, isConst, name); 00120 else 00121 data = new KConfigGroupPrivate(dynamic_cast<KConfig*>(master), isImmutable, isConst, name); 00122 return data; 00123 } 00124 00125 static QByteArray serializeList(const QList<QByteArray> &list); 00126 static QStringList deserializeList(const QString &data); 00127 }; 00128 00129 QByteArray KConfigGroupPrivate::serializeList(const QList<QByteArray> &list) 00130 { 00131 QByteArray value = ""; 00132 00133 if (!list.isEmpty()) { 00134 QList<QByteArray>::ConstIterator it = list.constBegin(); 00135 const QList<QByteArray>::ConstIterator end = list.constEnd(); 00136 00137 value = QByteArray(*it).replace('\\', "\\\\").replace(',', "\\,"); 00138 00139 while (++it != end) { 00140 // In the loop, so it is not done when there is only one element. 00141 // Doing it repeatedly is a pretty cheap operation. 00142 value.reserve(4096); 00143 00144 value += ','; 00145 value += QByteArray(*it).replace('\\', "\\\\").replace(',', "\\,"); 00146 } 00147 00148 // To be able to distinguish an empty list from a list with one empty element. 00149 if (value.isEmpty()) 00150 value = "\\0"; 00151 } 00152 00153 return value; 00154 } 00155 00156 QStringList KConfigGroupPrivate::deserializeList(const QString &data) 00157 { 00158 if (data.isEmpty()) 00159 return QStringList(); 00160 if (data == QLatin1String("\\0")) 00161 return QStringList(QString()); 00162 QStringList value; 00163 QString val; 00164 val.reserve(data.size()); 00165 bool quoted = false; 00166 for (int p = 0; p < data.length(); p++) { 00167 if (quoted) { 00168 val += data[p]; 00169 quoted = false; 00170 } else if (data[p].unicode() == '\\') { 00171 quoted = true; 00172 } else if (data[p].unicode() == ',') { 00173 val.squeeze(); // release any unused memory 00174 value.append(val); 00175 val.clear(); 00176 val.reserve(data.size() - p); 00177 } else { 00178 val += data[p]; 00179 } 00180 } 00181 value.append(val); 00182 return value; 00183 } 00184 00185 static QList<int> asIntList(const QByteArray& string) 00186 { 00187 QList<int> list; 00188 Q_FOREACH(const QByteArray& s, string.split(',')) 00189 list << s.toInt(); 00190 return list; 00191 } 00192 00193 static QList<qreal> asRealList(const QByteArray& string) 00194 { 00195 QList<qreal> list; 00196 Q_FOREACH(const QByteArray& s, string.split(',')) 00197 list << s.toDouble(); 00198 return list; 00199 } 00200 00201 static QString errString( const char * pKey, const QByteArray & value, const QVariant & aDefault ) { 00202 return QString::fromLatin1("\"%1\" - conversion of \"%3\" to %2 failed") 00203 .arg(QString::fromLatin1(pKey)) 00204 .arg(QString::fromLatin1(QVariant::typeToName(aDefault.type()))) 00205 .arg(QString::fromLatin1(value)); 00206 } 00207 00208 static QString formatError( int expected, int got ) { 00209 return QString::fromLatin1(" (wrong format: expected %1 items, got %2)").arg( expected ).arg( got ); 00210 } 00211 00212 QVariant KConfigGroup::convertToQVariant(const char *pKey, const QByteArray& value, const QVariant& aDefault) 00213 { 00214 // if a type handler is added here you must add a QVConversions definition 00215 // to conversion_check.h, or ConversionCheck::to_QVariant will not allow 00216 // readEntry<T> to convert to QVariant. 00217 switch( aDefault.type() ) { 00218 case QVariant::Invalid: 00219 return QVariant(); 00220 case QVariant::String: 00221 // this should return the raw string not the dollar expanded string. 00222 // imho if processed string is wanted should call 00223 // readEntry(key, QString) not readEntry(key, QVariant) 00224 return QString::fromUtf8(value); 00225 case QVariant::List: 00226 case QVariant::StringList: 00227 return KConfigGroupPrivate::deserializeList(QString::fromUtf8(value)); 00228 case QVariant::ByteArray: 00229 return value; 00230 case QVariant::Bool: { 00231 const QByteArray lower(value.toLower()); 00232 if (lower == "false" || lower == "no" || lower == "off" || lower == "0") 00233 return false; 00234 return true; 00235 } 00236 case QVariant::Double: 00237 case QMetaType::Float: 00238 case QVariant::Int: 00239 case QVariant::UInt: 00240 case QVariant::LongLong: 00241 case QVariant::ULongLong: { 00242 QVariant tmp = value; 00243 if ( !tmp.convert(aDefault.type()) ) 00244 tmp = aDefault; 00245 return tmp; 00246 } 00247 case QVariant::Point: { 00248 const QList<int> list = asIntList(value); 00249 00250 if ( list.count() != 2 ) { 00251 kError() << errString( pKey, value, aDefault ) 00252 << formatError( 2, list.count() ); 00253 return aDefault; 00254 } 00255 return QPoint(list.at( 0 ), list.at( 1 )); 00256 } 00257 case QVariant::PointF: { 00258 const QList<qreal> list = asRealList(value); 00259 00260 if ( list.count() != 2 ) { 00261 kError() << errString( pKey, value, aDefault ) 00262 << formatError( 2, list.count() ); 00263 return aDefault; 00264 } 00265 return QPointF(list.at( 0 ), list.at( 1 )); 00266 } 00267 case QVariant::Rect: { 00268 const QList<int> list = asIntList(value); 00269 00270 if ( list.count() != 4 ) { 00271 kError() << errString( pKey, value, aDefault ) 00272 << formatError( 4, list.count() ); 00273 return aDefault; 00274 } 00275 const QRect rect(list.at( 0 ), list.at( 1 ), list.at( 2 ), list.at( 3 )); 00276 if ( !rect.isValid() ) { 00277 kError() << errString( pKey, value, aDefault ); 00278 return aDefault; 00279 } 00280 return rect; 00281 } 00282 case QVariant::RectF: { 00283 const QList<qreal> list = asRealList(value); 00284 00285 if ( list.count() != 4 ) { 00286 kError() << errString( pKey, value, aDefault ) 00287 << formatError( 4, list.count() ); 00288 return aDefault; 00289 } 00290 const QRectF rect(list.at( 0 ), list.at( 1 ), list.at( 2 ), list.at( 3 )); 00291 if ( !rect.isValid() ) { 00292 kError() << errString( pKey, value, aDefault ); 00293 return aDefault; 00294 } 00295 return rect; 00296 } 00297 case QVariant::Size: { 00298 const QList<int> list = asIntList(value); 00299 00300 if ( list.count() != 2 ) { 00301 kError() << errString( pKey, value, aDefault ) 00302 << formatError( 2, list.count() ); 00303 return aDefault; 00304 } 00305 const QSize size(list.at( 0 ), list.at( 1 )); 00306 if ( !size.isValid() ) { 00307 kError() << errString( pKey, value, aDefault ); 00308 return aDefault; 00309 } 00310 return size; 00311 } 00312 case QVariant::SizeF: { 00313 const QList<qreal> list = asRealList(value); 00314 00315 if ( list.count() != 2 ) { 00316 kError() << errString( pKey, value, aDefault ) 00317 << formatError( 2, list.count() ); 00318 return aDefault; 00319 } 00320 const QSizeF size(list.at( 0 ), list.at( 1 )); 00321 if ( !size.isValid() ) { 00322 kError() << errString( pKey, value, aDefault ); 00323 return aDefault; 00324 } 00325 return size; 00326 } 00327 case QVariant::DateTime: { 00328 const QList<int> list = asIntList(value); 00329 if ( list.count() != 6 ) { 00330 kError() << errString( pKey, value, aDefault ) 00331 << formatError( 6, list.count() ); 00332 return aDefault; 00333 } 00334 const QDate date( list.at( 0 ), list.at( 1 ), list.at( 2 ) ); 00335 const QTime time( list.at( 3 ), list.at( 4 ), list.at( 5 ) ); 00336 const QDateTime dt( date, time ); 00337 if ( !dt.isValid() ) { 00338 kError() << errString( pKey, value, aDefault ); 00339 return aDefault; 00340 } 00341 return dt; 00342 } 00343 case QVariant::Date: { 00344 QList<int> list = asIntList(value); 00345 if ( list.count() == 6 ) 00346 list = list.mid(0, 3); // don't break config files that stored QDate as QDateTime 00347 if ( list.count() != 3 ) { 00348 kError() << errString( pKey, value, aDefault ) 00349 << formatError( 3, list.count() ); 00350 return aDefault; 00351 } 00352 const QDate date( list.at( 0 ), list.at( 1 ), list.at( 2 ) ); 00353 if ( !date.isValid() ) { 00354 kError() << errString( pKey, value, aDefault ); 00355 return aDefault; 00356 } 00357 return date; 00358 } 00359 case QVariant::Color: 00360 case QVariant::Font: 00361 kWarning() << "KConfigGroup::readEntry was passed GUI type '" 00362 << aDefault.typeName() 00363 << "' but kdeui isn't linked! If it is linked to your program, " 00364 "this is a platform bug. Please inform the KDE developers"; 00365 break; 00366 case QVariant::Url: 00367 return QUrl(QString::fromUtf8(value)); 00368 00369 default: 00370 if( aDefault.canConvert<KUrl>() ) { 00371 const KUrl url(QString::fromUtf8(value)); 00372 return qVariantFromValue<KUrl>( url ); 00373 } 00374 break; 00375 } 00376 00377 kWarning() << "unhandled type " << aDefault.typeName(); 00378 return QVariant(); 00379 } 00380 00381 QString KConfigGroupPrivate::expandString(const QString& value) 00382 { 00383 QString aValue = value; 00384 00385 // check for environment variables and make necessary translations 00386 int nDollarPos = aValue.indexOf( QLatin1Char('$') ); 00387 while( nDollarPos != -1 && nDollarPos+1 < aValue.length()) { 00388 // there is at least one $ 00389 if( aValue[nDollarPos+1] == QLatin1Char('(') ) { 00390 int nEndPos = nDollarPos+1; 00391 // the next character is not $ 00392 while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!=QLatin1Char(')')) ) 00393 nEndPos++; 00394 nEndPos++; 00395 QString cmd = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); 00396 00397 QString result; 00398 QByteArray oldpath = qgetenv( "PATH" ); 00399 QByteArray newpath; 00400 if (KGlobal::hasMainComponent()) { 00401 newpath = QFile::encodeName(KGlobal::dirs()->resourceDirs("exe").join(QChar::fromLatin1(KPATH_SEPARATOR))); 00402 if (!newpath.isEmpty() && !oldpath.isEmpty()) 00403 newpath += KPATH_SEPARATOR; 00404 } 00405 newpath += oldpath; 00406 setenv( "PATH", newpath, 1/*overwrite*/ ); 00407 // FIXME: wince does not have pipes 00408 #ifndef _WIN32_WCE 00409 FILE *fs = popen(QFile::encodeName(cmd).data(), "r"); 00410 if (fs) { 00411 QTextStream ts(fs, QIODevice::ReadOnly); 00412 result = ts.readAll().trimmed(); 00413 pclose(fs); 00414 } 00415 #endif 00416 setenv( "PATH", oldpath, 1/*overwrite*/ ); 00417 aValue.replace( nDollarPos, nEndPos-nDollarPos, result ); 00418 nDollarPos += result.length(); 00419 } else if( aValue[nDollarPos+1] != QLatin1Char('$') ) { 00420 int nEndPos = nDollarPos+1; 00421 // the next character is not $ 00422 QString aVarName; 00423 if ( aValue[nEndPos] == QLatin1Char('{') ) { 00424 while ( (nEndPos <= aValue.length()) && (aValue[nEndPos] != QLatin1Char('}')) ) 00425 nEndPos++; 00426 nEndPos++; 00427 aVarName = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); 00428 } else { 00429 while ( nEndPos <= aValue.length() && 00430 (aValue[nEndPos].isNumber() || 00431 aValue[nEndPos].isLetter() || 00432 aValue[nEndPos] == QLatin1Char('_') ) ) 00433 nEndPos++; 00434 aVarName = aValue.mid( nDollarPos+1, nEndPos-nDollarPos-1 ); 00435 } 00436 QString env; 00437 if (!aVarName.isEmpty()) { 00438 #ifdef Q_OS_WIN 00439 if (aVarName == QLatin1String("HOME")) 00440 env = QDir::homePath(); 00441 else 00442 #endif 00443 { 00444 QByteArray pEnv = qgetenv( aVarName.toAscii() ); 00445 if( !pEnv.isEmpty() ) 00446 // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!! 00447 // An environment variable may contain values in 8bit 00448 // locale specified encoding or UTF8 encoding 00449 env = KStringHandler::from8Bit( pEnv ); 00450 } 00451 aValue.replace(nDollarPos, nEndPos-nDollarPos, env); 00452 nDollarPos += env.length(); 00453 } else 00454 aValue.remove( nDollarPos, nEndPos-nDollarPos ); 00455 } else { 00456 // remove one of the dollar signs 00457 aValue.remove( nDollarPos, 1 ); 00458 nDollarPos++; 00459 } 00460 nDollarPos = aValue.indexOf( QLatin1Char('$'), nDollarPos ); 00461 } 00462 00463 return aValue; 00464 } 00465 00466 #ifdef Q_WS_WIN 00467 # include <QtCore/QDir> 00468 #endif 00469 00470 static bool cleanHomeDirPath( QString &path, const QString &homeDir ) 00471 { 00472 #ifdef Q_WS_WIN //safer 00473 if (!QDir::convertSeparators(path).startsWith(QDir::convertSeparators(homeDir))) 00474 return false; 00475 #else 00476 if (!path.startsWith(homeDir)) 00477 return false; 00478 #endif 00479 00480 int len = homeDir.length(); 00481 // replace by "$HOME" if possible 00482 if (len && (path.length() == len || path[len] == QLatin1Char('/'))) { 00483 path.replace(0, len, QString::fromLatin1("$HOME")); 00484 return true; 00485 } else 00486 return false; 00487 } 00488 00489 static QString translatePath( QString path ) // krazy:exclude=passbyvalue 00490 { 00491 if (path.isEmpty()) 00492 return path; 00493 00494 // only "our" $HOME should be interpreted 00495 path.replace(QLatin1Char('$'), QLatin1String("$$")); 00496 00497 bool startsWithFile = path.startsWith(QLatin1String("file:"), Qt::CaseInsensitive); 00498 00499 // return original path, if it refers to another type of URL (e.g. http:/), or 00500 // if the path is already relative to another directory 00501 if ((!startsWithFile && QFileInfo(path).isRelative()) || 00502 (startsWithFile && QFileInfo(path.mid(5)).isRelative())) 00503 return path; 00504 00505 if (startsWithFile) 00506 path.remove(0,5); // strip leading "file:/" off the string 00507 00508 // keep only one single '/' at the beginning - needed for cleanHomeDirPath() 00509 while (path[0] == QLatin1Char('/') && path[1] == QLatin1Char('/')) 00510 path.remove(0,1); 00511 00512 // we can not use KGlobal::dirs()->relativeLocation("home", path) here, 00513 // since it would not recognize paths without a trailing '/'. 00514 // All of the 3 following functions to return the user's home directory 00515 // can return different paths. We have to test all them. 00516 const QString homeDir0 = QFile::decodeName(qgetenv("HOME")); 00517 const QString homeDir1 = QDir::homePath(); 00518 const QString homeDir2 = QDir(homeDir1).canonicalPath(); 00519 if (cleanHomeDirPath(path, homeDir0) || 00520 cleanHomeDirPath(path, homeDir1) || 00521 cleanHomeDirPath(path, homeDir2) ) { 00522 // kDebug() << "Path was replaced\n"; 00523 } 00524 00525 if (startsWithFile) 00526 path.prepend(QString::fromLatin1("file://")); 00527 00528 return path; 00529 } 00530 00531 00532 KConfigGroup::KConfigGroup() : d(0) 00533 { 00534 } 00535 00536 bool KConfigGroup::isValid() const 00537 { 00538 return 0 != d.constData(); 00539 } 00540 00541 KConfigGroupGui _kde_internal_KConfigGroupGui; 00542 static inline bool readEntryGui(const QByteArray& data, const char* key, const QVariant &input, 00543 QVariant &output) 00544 { 00545 if (_kde_internal_KConfigGroupGui.readEntryGui) 00546 return _kde_internal_KConfigGroupGui.readEntryGui(data, key, input, output); 00547 return false; 00548 } 00549 00550 static inline bool writeEntryGui(KConfigGroup *cg, const char* key, const QVariant &input, 00551 KConfigGroup::WriteConfigFlags flags) 00552 { 00553 if (_kde_internal_KConfigGroupGui.writeEntryGui) 00554 return _kde_internal_KConfigGroupGui.writeEntryGui(cg, key, input, flags); 00555 return false; 00556 } 00557 00558 KConfigGroup::KConfigGroup(KConfigBase *master, const QString &_group) 00559 : d(KConfigGroupPrivate::create(master, _group.toUtf8(), master->isGroupImmutable(_group), false)) 00560 { 00561 } 00562 00563 KConfigGroup::KConfigGroup(KConfigBase *master, const char *_group) 00564 : d(KConfigGroupPrivate::create(master, _group, master->isGroupImmutable(_group), false)) 00565 { 00566 } 00567 00568 KConfigGroup::KConfigGroup(const KConfigBase *master, const QString &_group) 00569 : d(KConfigGroupPrivate::create(const_cast<KConfigBase*>(master), _group.toUtf8(), master->isGroupImmutable(_group), true)) 00570 { 00571 } 00572 00573 KConfigGroup::KConfigGroup(const KConfigBase *master, const char * _group) 00574 : d(KConfigGroupPrivate::create(const_cast<KConfigBase*>(master), _group, master->isGroupImmutable(_group), true)) 00575 { 00576 } 00577 00578 KConfigGroup::KConfigGroup(const KSharedConfigPtr &master, const QString &_group) 00579 : d(new KConfigGroupPrivate(master, _group.toUtf8())) 00580 { 00581 } 00582 00583 KConfigGroup::KConfigGroup(const KSharedConfigPtr &master, const char * _group) 00584 : d(new KConfigGroupPrivate(master, _group)) 00585 { 00586 } 00587 00588 KConfigGroup &KConfigGroup::operator=(const KConfigGroup &rhs) 00589 { 00590 d = rhs.d; 00591 return *this; 00592 } 00593 00594 KConfigGroup::KConfigGroup(const KConfigGroup &rhs) 00595 : KConfigBase(), d(rhs.d) 00596 { 00597 } 00598 00599 KConfigGroup::~KConfigGroup() 00600 { 00601 d = 0; 00602 } 00603 00604 KConfigGroup KConfigGroup::groupImpl(const QByteArray& aGroup) 00605 { 00606 Q_ASSERT_X(isValid(), "KConfigGroup::groupImpl", "accessing an invalid group"); 00607 Q_ASSERT_X(!aGroup.isEmpty(), "KConfigGroup::groupImpl", "can not have an unnamed child group"); 00608 00609 KConfigGroup newGroup; 00610 00611 newGroup.d = new KConfigGroupPrivate(this, isGroupImmutableImpl(aGroup), d->bConst, aGroup); 00612 00613 return newGroup; 00614 } 00615 00616 const KConfigGroup KConfigGroup::groupImpl(const QByteArray& aGroup) const 00617 { 00618 Q_ASSERT_X(isValid(), "KConfigGroup::groupImpl", "accessing an invalid group"); 00619 Q_ASSERT_X(!aGroup.isEmpty(), "KConfigGroup::groupImpl", "can not have an unnamed child group"); 00620 00621 KConfigGroup newGroup; 00622 00623 newGroup.d = new KConfigGroupPrivate(const_cast<KConfigGroup*>(this), isGroupImmutableImpl(aGroup), 00624 true, aGroup); 00625 00626 return newGroup; 00627 } 00628 00629 KConfigGroup KConfigGroup::parent() const 00630 { 00631 Q_ASSERT_X(isValid(), "KConfigGroup::parent", "accessing an invalid group"); 00632 00633 KConfigGroup parentGroup; 00634 00635 if (d->mParent) { 00636 parentGroup.d = d->mParent; 00637 } else { 00638 parentGroup.d = new KConfigGroupPrivate(d->mOwner, d->mOwner->isImmutable(), d->bConst, ""); 00639 // make sure we keep the refcount up on the KConfig object 00640 parentGroup.d->sOwner = d->sOwner; 00641 } 00642 00643 return parentGroup; 00644 } 00645 00646 void KConfigGroup::deleteGroup(WriteConfigFlags flags) 00647 { 00648 Q_ASSERT_X(isValid(), "KConfigGroup::deleteGroup", "accessing an invalid group"); 00649 Q_ASSERT_X(!d->bConst, "KConfigGroup::deleteGroup", "deleting a read-only group"); 00650 00651 config()->deleteGroup(d->fullName(), flags); 00652 } 00653 00654 #ifndef KDE_NO_DEPRECATED 00655 void KConfigGroup::changeGroup( const QString &group ) 00656 { 00657 Q_ASSERT_X(isValid(), "KConfigGroup::changeGroup", "accessing an invalid group"); 00658 d.detach(); 00659 d->mName = group.toUtf8(); 00660 } 00661 #endif 00662 00663 #ifndef KDE_NO_DEPRECATED 00664 void KConfigGroup::changeGroup( const char *group ) 00665 { 00666 Q_ASSERT_X(isValid(), "KConfigGroup::changeGroup", "accessing an invalid group"); 00667 d.detach(); 00668 d->mName = group; 00669 } 00670 #endif 00671 00672 QString KConfigGroup::name() const 00673 { 00674 Q_ASSERT_X(isValid(), "KConfigGroup::name", "accessing an invalid group"); 00675 00676 return QString::fromUtf8(d->name()); 00677 } 00678 00679 bool KConfigGroup::exists() const 00680 { 00681 Q_ASSERT_X(isValid(), "KConfigGroup::exists", "accessing an invalid group"); 00682 00683 return config()->hasGroup( d->fullName() ); 00684 } 00685 00686 void KConfigGroup::sync() 00687 { 00688 Q_ASSERT_X(isValid(), "KConfigGroup::sync", "accessing an invalid group"); 00689 00690 if (!d->bConst) 00691 config()->sync(); 00692 } 00693 00694 QMap<QString, QString> KConfigGroup::entryMap() const 00695 { 00696 Q_ASSERT_X(isValid(), "KConfigGroup::entryMap", "accessing an invalid group"); 00697 00698 return config()->entryMap(QString::fromUtf8(d->fullName())); 00699 } 00700 00701 KConfig* KConfigGroup::config() 00702 { 00703 Q_ASSERT_X(isValid(), "KConfigGroup::config", "accessing an invalid group"); 00704 00705 return d->mOwner; 00706 } 00707 00708 const KConfig* KConfigGroup::config() const 00709 { 00710 Q_ASSERT_X(isValid(), "KConfigGroup::config", "accessing an invalid group"); 00711 00712 return d->mOwner; 00713 } 00714 00715 bool KConfigGroup::isEntryImmutable(const char* key) const 00716 { 00717 Q_ASSERT_X(isValid(), "KConfigGroup::isEntryImmutable", "accessing an invalid group"); 00718 00719 return (isImmutable() || 00720 !config()->d_func()->canWriteEntry(d->fullName(), key, config()->readDefaults())); 00721 } 00722 00723 bool KConfigGroup::isEntryImmutable(const QString& key) const 00724 { 00725 return isEntryImmutable(key.toUtf8().constData()); 00726 } 00727 00728 QString KConfigGroup::readEntryUntranslated(const QString& pKey, const QString& aDefault) const 00729 { 00730 return readEntryUntranslated(pKey.toUtf8().constData(), aDefault); 00731 } 00732 00733 QString KConfigGroup::readEntryUntranslated(const char *key, const QString& aDefault) const 00734 { 00735 Q_ASSERT_X(isValid(), "KConfigGroup::readEntryUntranslated", "accessing an invalid group"); 00736 00737 QString result = config()->d_func()->lookupData(d->fullName(), key, KEntryMap::SearchFlags(), 0); 00738 if (result.isNull()) 00739 return aDefault; 00740 return result; 00741 } 00742 00743 QString KConfigGroup::readEntry(const char *key, const char* aDefault) const 00744 { 00745 return readEntry(key, QString::fromUtf8(aDefault)); 00746 } 00747 00748 QString KConfigGroup::readEntry(const QString &key, const char* aDefault) const 00749 { 00750 return readEntry(key.toUtf8().constData(), aDefault); 00751 } 00752 00753 QString KConfigGroup::readEntry(const char* key, const QString& aDefault) const 00754 { 00755 Q_ASSERT_X(isValid(), "KConfigGroup::readEntry", "accessing an invalid group"); 00756 00757 bool expand = false; 00758 00759 // read value from the entry map 00760 QString aValue = config()->d_func()->lookupData(d->fullName(), key, KEntryMap::SearchLocalized, 00761 &expand); 00762 if (aValue.isNull()) 00763 aValue = aDefault; 00764 00765 if (expand) 00766 return KConfigGroupPrivate::expandString(aValue); 00767 00768 return aValue; 00769 } 00770 00771 QString KConfigGroup::readEntry(const QString &key, const QString& aDefault) const 00772 { 00773 return readEntry(key.toUtf8().constData(), aDefault); 00774 } 00775 00776 QStringList KConfigGroup::readEntry(const char* key, const QStringList& aDefault) const 00777 { 00778 Q_ASSERT_X(isValid(), "KConfigGroup::readEntry", "accessing an invalid group"); 00779 00780 const QString data = readEntry(key, QString()); 00781 if (data.isNull()) 00782 return aDefault; 00783 00784 return KConfigGroupPrivate::deserializeList(data); 00785 } 00786 00787 QStringList KConfigGroup::readEntry( const QString& key, const QStringList& aDefault) const 00788 { 00789 return readEntry( key.toUtf8().constData(), aDefault ); 00790 } 00791 00792 QVariant KConfigGroup::readEntry( const char* key, const QVariant &aDefault ) const 00793 { 00794 Q_ASSERT_X(isValid(), "KConfigGroup::readEntry", "accessing an invalid group"); 00795 00796 const QByteArray data = config()->d_func()->lookupData(d->fullName(), key, KEntryMap::SearchLocalized); 00797 if (data.isNull()) 00798 return aDefault; 00799 00800 QVariant value; 00801 if (!readEntryGui( data, key, aDefault, value )) 00802 return convertToQVariant(key, data, aDefault); 00803 00804 return value; 00805 } 00806 00807 QVariant KConfigGroup::readEntry( const QString& key, const QVariant& aDefault) const 00808 { 00809 return readEntry( key.toUtf8().constData(), aDefault ); 00810 } 00811 00812 QVariantList KConfigGroup::readEntry( const char* key, const QVariantList& aDefault) const 00813 { 00814 Q_ASSERT_X(isValid(), "KConfigGroup::readEntry", "accessing an invalid group"); 00815 00816 const QString data = readEntry(key, QString()); 00817 if (data.isNull()) 00818 return aDefault; 00819 00820 QVariantList value; 00821 foreach(const QString& v, KConfigGroupPrivate::deserializeList(data)) 00822 value << v; 00823 00824 return value; 00825 } 00826 00827 QVariantList KConfigGroup::readEntry( const QString& key, const QVariantList& aDefault) const 00828 { 00829 return readEntry( key.toUtf8().constData(), aDefault ); 00830 } 00831 00832 QStringList KConfigGroup::readXdgListEntry(const QString& key, const QStringList& aDefault) const 00833 { 00834 return readXdgListEntry(key.toUtf8().constData(), aDefault); 00835 } 00836 00837 QStringList KConfigGroup::readXdgListEntry(const char *key, const QStringList& aDefault) const 00838 { 00839 Q_ASSERT_X(isValid(), "KConfigGroup::readXdgListEntry", "accessing an invalid group"); 00840 00841 const QString data = readEntry(key, QString()); 00842 if (data.isNull()) 00843 return aDefault; 00844 00845 QStringList value; 00846 QString val; 00847 val.reserve(data.size()); 00848 // XXX List serialization being a separate layer from low-level parsing is 00849 // probably a bug. No affected entries are defined, though. 00850 bool quoted = false; 00851 for (int p = 0; p < data.length(); p++) { 00852 if (quoted) { 00853 val += data[p]; 00854 quoted = false; 00855 } else if (data[p] == QLatin1Char('\\')) { 00856 quoted = true; 00857 } else if (data[p] == QLatin1Char(';')) { 00858 value.append(val); 00859 val.clear(); 00860 val.reserve(data.size() - p); 00861 } else { 00862 val += data[p]; 00863 } 00864 } 00865 if (!val.isEmpty()) { 00866 kWarning() << "List entry" << key << "in" << config()->name() << "is not compliant with XDG standard (missing trailing semicolon)."; 00867 value.append(val); 00868 } 00869 return value; 00870 } 00871 00872 QString KConfigGroup::readPathEntry(const QString& pKey, const QString & aDefault) const 00873 { 00874 return readPathEntry(pKey.toUtf8().constData(), aDefault); 00875 } 00876 00877 QString KConfigGroup::readPathEntry(const char *key, const QString & aDefault) const 00878 { 00879 Q_ASSERT_X(isValid(), "KConfigGroup::readPathEntry", "accessing an invalid group"); 00880 00881 bool expand = false; 00882 00883 QString aValue = config()->d_func()->lookupData(d->fullName(), key, KEntryMap::SearchLocalized, 00884 &expand); 00885 if (aValue.isNull()) 00886 aValue = aDefault; 00887 00888 return KConfigGroupPrivate::expandString(aValue); 00889 } 00890 00891 QStringList KConfigGroup::readPathEntry(const QString& pKey, const QStringList& aDefault) const 00892 { 00893 return readPathEntry(pKey.toUtf8().constData(), aDefault); 00894 } 00895 00896 QStringList KConfigGroup::readPathEntry(const char *key, const QStringList& aDefault) const 00897 { 00898 Q_ASSERT_X(isValid(), "KConfigGroup::readPathEntry", "accessing an invalid group"); 00899 00900 const QString data = readPathEntry(key, QString()); 00901 if (data.isNull()) 00902 return aDefault; 00903 00904 return KConfigGroupPrivate::deserializeList(data); 00905 } 00906 00907 void KConfigGroup::writeEntry( const char* key, const QString& value, WriteConfigFlags flags ) 00908 { 00909 Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group"); 00910 Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group"); 00911 00912 writeEntry(key, value.toUtf8(), flags); 00913 } 00914 00915 void KConfigGroup::writeEntry( const QString& key, const QString& value, WriteConfigFlags flags ) 00916 { 00917 writeEntry(key.toUtf8().constData(), value, flags); 00918 } 00919 00920 void KConfigGroup::writeEntry(const QString &key, const char *value, WriteConfigFlags pFlags) 00921 { 00922 Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group"); 00923 Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group"); 00924 00925 writeEntry(key.toUtf8().constData(), QVariant(QString::fromLatin1(value)), pFlags); 00926 } 00927 00928 void KConfigGroup::writeEntry(const char *key, const char *value, WriteConfigFlags pFlags) 00929 { 00930 writeEntry(key, QVariant(QString::fromLatin1(value)), pFlags); 00931 } 00932 00933 void KConfigGroup::writeEntry( const char* key, const QByteArray& value, 00934 WriteConfigFlags flags ) 00935 { 00936 Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group"); 00937 Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group"); 00938 00939 config()->d_func()->putData(d->fullName(), key, value.isNull()? QByteArray(""): value, flags); 00940 } 00941 00942 void KConfigGroup::writeEntry(const QString& key, const QByteArray& value, 00943 WriteConfigFlags pFlags) 00944 { 00945 writeEntry(key.toUtf8().constData(), value, pFlags); 00946 } 00947 00948 void KConfigGroup::writeEntry(const char* key, const QStringList &list, WriteConfigFlags flags) 00949 { 00950 Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group"); 00951 Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group"); 00952 00953 QList<QByteArray> balist; 00954 00955 foreach(const QString &entry, list) 00956 balist.append(entry.toUtf8()); 00957 00958 writeEntry(key, KConfigGroupPrivate::serializeList(balist), flags); 00959 } 00960 00961 void KConfigGroup::writeEntry(const QString& key, const QStringList &list, WriteConfigFlags flags) 00962 { 00963 writeEntry(key.toUtf8().constData(), list, flags); 00964 } 00965 00966 void KConfigGroup::writeEntry( const char* key, const QVariantList& list, WriteConfigFlags flags ) 00967 { 00968 Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group"); 00969 Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group"); 00970 00971 QList<QByteArray> data; 00972 00973 foreach(const QVariant& v, list) { 00974 if (v.type() == QVariant::ByteArray) 00975 data << v.toByteArray(); 00976 else 00977 data << v.toString().toUtf8(); 00978 } 00979 00980 writeEntry(key, KConfigGroupPrivate::serializeList(data), flags); 00981 } 00982 00983 void KConfigGroup::writeEntry( const char* key, const QVariant &value, 00984 WriteConfigFlags flags ) 00985 { 00986 Q_ASSERT_X(isValid(), "KConfigGroup::writeEntry", "accessing an invalid group"); 00987 Q_ASSERT_X(!d->bConst, "KConfigGroup::writeEntry", "writing to a read-only group"); 00988 00989 if ( writeEntryGui( this, key, value, flags ) ) 00990 return; // GUI type that was handled 00991 00992 QByteArray data; 00993 // if a type handler is added here you must add a QVConversions definition 00994 // to conversion_check.h, or ConversionCheck::to_QVariant will not allow 00995 // writeEntry<T> to convert to QVariant. 00996 switch( value.type() ) { 00997 case QVariant::Invalid: 00998 data = ""; 00999 break; 01000 case QVariant::ByteArray: 01001 data = value.toByteArray(); 01002 break; 01003 case QVariant::String: 01004 case QVariant::Int: 01005 case QVariant::UInt: 01006 case QVariant::Double: 01007 case QMetaType::Float: 01008 case QVariant::Bool: 01009 case QVariant::LongLong: 01010 case QVariant::ULongLong: 01011 data = value.toString().toUtf8(); 01012 break; 01013 case QVariant::List: 01014 kError(!value.canConvert(QVariant::StringList)) 01015 << "not all types in \"" << key << "\" can convert to QString," 01016 " information will be lost"; 01017 case QVariant::StringList: 01018 writeEntry( key, value.toList(), flags ); 01019 return; 01020 case QVariant::Point: { 01021 QVariantList list; 01022 const QPoint rPoint = value.toPoint(); 01023 list.insert( 0, rPoint.x() ); 01024 list.insert( 1, rPoint.y() ); 01025 01026 writeEntry( key, list, flags ); 01027 return; 01028 } 01029 case QVariant::PointF: { 01030 QVariantList list; 01031 const QPointF point = value.toPointF(); 01032 list.insert( 0, point.x() ); 01033 list.insert( 1, point.y() ); 01034 01035 writeEntry( key, list, flags ); 01036 return; 01037 } 01038 case QVariant::Rect:{ 01039 QVariantList list; 01040 const QRect rRect = value.toRect(); 01041 list.insert( 0, rRect.left() ); 01042 list.insert( 1, rRect.top() ); 01043 list.insert( 2, rRect.width() ); 01044 list.insert( 3, rRect.height() ); 01045 01046 writeEntry( key, list, flags ); 01047 return; 01048 } 01049 case QVariant::RectF:{ 01050 QVariantList list; 01051 const QRectF rRectF = value.toRectF(); 01052 list.insert(0, rRectF.left()); 01053 list.insert(1, rRectF.top()); 01054 list.insert(2, rRectF.width()); 01055 list.insert(3, rRectF.height()); 01056 01057 writeEntry(key, list, flags); 01058 return; 01059 } 01060 case QVariant::Size:{ 01061 QVariantList list; 01062 const QSize rSize = value.toSize(); 01063 list.insert( 0, rSize.width() ); 01064 list.insert( 1, rSize.height() ); 01065 01066 writeEntry( key, list, flags ); 01067 return; 01068 } 01069 case QVariant::SizeF:{ 01070 QVariantList list; 01071 const QSizeF rSizeF = value.toSizeF(); 01072 list.insert(0, rSizeF.width()); 01073 list.insert(1, rSizeF.height()); 01074 01075 writeEntry(key, list, flags); 01076 return; 01077 } 01078 case QVariant::Date: { 01079 QVariantList list; 01080 const QDate date = value.toDate(); 01081 01082 list.insert( 0, date.year() ); 01083 list.insert( 1, date.month() ); 01084 list.insert( 2, date.day() ); 01085 01086 writeEntry( key, list, flags ); 01087 return; 01088 } 01089 case QVariant::DateTime: { 01090 QVariantList list; 01091 const QDateTime rDateTime = value.toDateTime(); 01092 01093 const QTime time = rDateTime.time(); 01094 const QDate date = rDateTime.date(); 01095 01096 list.insert( 0, date.year() ); 01097 list.insert( 1, date.month() ); 01098 list.insert( 2, date.day() ); 01099 01100 list.insert( 3, time.hour() ); 01101 list.insert( 4, time.minute() ); 01102 list.insert( 5, time.second() ); 01103 01104 writeEntry( key, list, flags ); 01105 return; 01106 } 01107 01108 case QVariant::Color: 01109 case QVariant::Font: 01110 kWarning() << "KConfigGroup::writeEntry was passed GUI type '" 01111 << value.typeName() 01112 << "' but kdeui isn't linked! If it is linked to your program, this is a platform bug. " 01113 "Please inform the KDE developers"; 01114 break; 01115 case QVariant::Url: 01116 data = KUrl(value.toUrl()).url().toUtf8(); 01117 break; 01118 default: 01119 if( value.canConvert<KUrl>() ) { 01120 data = qvariant_cast<KUrl>(value).url().toUtf8(); 01121 break; 01122 } 01123 kWarning() << "KConfigGroup::writeEntry - unhandled type" << value.typeName() << "in group" << name(); 01124 } 01125 01126 writeEntry(key, data, flags); 01127 } 01128 01129 void KConfigGroup::writeEntry( const QString& key, const QVariant& value, WriteConfigFlags flags ) 01130 { 01131 writeEntry(key.toUtf8().constData(), value, flags); 01132 } 01133 01134 void KConfigGroup::writeEntry(const QString& key, const QVariantList &list, WriteConfigFlags flags) 01135 { 01136 writeEntry(key.toUtf8().constData(), list, flags); 01137 } 01138 01139 void KConfigGroup::writeXdgListEntry(const QString& key, const QStringList &value, WriteConfigFlags pFlags) 01140 { 01141 writeXdgListEntry(key.toUtf8().constData(), value, pFlags); 01142 } 01143 01144 void KConfigGroup::writeXdgListEntry(const char *key, const QStringList &list, WriteConfigFlags flags) 01145 { 01146 Q_ASSERT_X(isValid(), "KConfigGroup::writeXdgListEntry", "accessing an invalid group"); 01147 Q_ASSERT_X(!d->bConst, "KConfigGroup::writeXdgListEntry", "writing to a read-only group"); 01148 01149 QString value; 01150 value.reserve(4096); 01151 01152 // XXX List serialization being a separate layer from low-level escaping is 01153 // probably a bug. No affected entries are defined, though. 01154 QStringList::ConstIterator it = list.constBegin(); 01155 const QStringList::ConstIterator end = list.constEnd(); 01156 for (; it != end; ++it) { 01157 QString val(*it); 01158 val.replace(QLatin1Char('\\'), QLatin1String("\\\\")).replace(QLatin1Char(';'), QLatin1String("\\;")); 01159 value += val; 01160 value += QLatin1Char(';'); 01161 } 01162 01163 writeEntry(key, value, flags); 01164 } 01165 01166 void KConfigGroup::writePathEntry(const QString& pKey, const QString & path, WriteConfigFlags pFlags) 01167 { 01168 writePathEntry(pKey.toUtf8().constData(), path, pFlags); 01169 } 01170 01171 void KConfigGroup::writePathEntry(const char *pKey, const QString & path, WriteConfigFlags pFlags) 01172 { 01173 Q_ASSERT_X(isValid(), "KConfigGroup::writePathEntry", "accessing an invalid group"); 01174 Q_ASSERT_X(!d->bConst, "KConfigGroup::writePathEntry", "writing to a read-only group"); 01175 01176 config()->d_func()->putData(d->fullName(), pKey, translatePath(path).toUtf8(), pFlags, true); 01177 } 01178 01179 void KConfigGroup::writePathEntry(const QString& pKey, const QStringList &value, WriteConfigFlags pFlags) 01180 { 01181 writePathEntry(pKey.toUtf8().constData(), value, pFlags); 01182 } 01183 01184 void KConfigGroup::writePathEntry(const char *pKey, const QStringList &value, WriteConfigFlags pFlags) 01185 { 01186 Q_ASSERT_X(isValid(), "KConfigGroup::writePathEntry", "accessing an invalid group"); 01187 Q_ASSERT_X(!d->bConst, "KConfigGroup::writePathEntry", "writing to a read-only group"); 01188 01189 QList<QByteArray> list; 01190 foreach(const QString& path, value) 01191 list << translatePath(path).toUtf8(); 01192 01193 config()->d_func()->putData(d->fullName(), pKey, KConfigGroupPrivate::serializeList(list), pFlags, true); 01194 } 01195 01196 void KConfigGroup::deleteEntry( const char *key, WriteConfigFlags flags) 01197 { 01198 Q_ASSERT_X(isValid(), "KConfigGroup::deleteEntry", "accessing an invalid group"); 01199 Q_ASSERT_X(!d->bConst, "KConfigGroup::deleteEntry", "deleting from a read-only group"); 01200 01201 config()->d_func()->putData(d->fullName(), key, QByteArray(), flags); 01202 } 01203 01204 void KConfigGroup::deleteEntry( const QString& key, WriteConfigFlags flags) 01205 { 01206 deleteEntry(key.toUtf8().constData(), flags); 01207 } 01208 01209 void KConfigGroup::revertToDefault(const char *key) 01210 { 01211 Q_ASSERT_X(isValid(), "KConfigGroup::revertToDefault", "accessing an invalid group"); 01212 Q_ASSERT_X(!d->bConst, "KConfigGroup::revertToDefault", "writing to a read-only group"); 01213 01214 const QByteArray theDefault = config()->d_func()->lookupData(d->fullName(), key, 01215 KEntryMap::SearchDefaults|KEntryMap::SearchLocalized); 01216 01217 config()->d_func()->putData(d->fullName(), key, theDefault, KConfig::Normal); 01218 } 01219 01220 void KConfigGroup::revertToDefault(const QString &key) 01221 { 01222 revertToDefault(key.toUtf8().constData()); 01223 } 01224 01225 bool KConfigGroup::hasDefault(const char *key) const 01226 { 01227 Q_ASSERT_X(isValid(), "KConfigGroup::hasDefault", "accessing an invalid group"); 01228 01229 KEntryMap::SearchFlags flags = KEntryMap::SearchDefaults|KEntryMap::SearchLocalized; 01230 01231 return !config()->d_func()->lookupData(d->fullName(), key, flags).isNull(); 01232 } 01233 01234 bool KConfigGroup::hasDefault(const QString &key) const 01235 { 01236 return hasDefault(key.toUtf8().constData()); 01237 } 01238 01239 bool KConfigGroup::hasKey(const char *key) const 01240 { 01241 Q_ASSERT_X(isValid(), "KConfigGroup::hasKey", "accessing an invalid group"); 01242 01243 KEntryMap::SearchFlags flags = KEntryMap::SearchLocalized; 01244 if ( config()->readDefaults() ) 01245 flags |= KEntryMap::SearchDefaults; 01246 01247 return !config()->d_func()->lookupData(d->fullName(), key, flags).isNull(); 01248 } 01249 01250 bool KConfigGroup::hasKey(const QString &key) const 01251 { 01252 return hasKey(key.toUtf8().constData()); 01253 } 01254 01255 bool KConfigGroup::isImmutable() const 01256 { 01257 Q_ASSERT_X(isValid(), "KConfigGroup::isImmutable", "accessing an invalid group"); 01258 01259 return d->bImmutable; 01260 } 01261 01262 QStringList KConfigGroup::groupList() const 01263 { 01264 Q_ASSERT_X(isValid(), "KConfigGroup::groupList", "accessing an invalid group"); 01265 01266 return config()->d_func()->groupList(d->fullName()); 01267 } 01268 01269 QStringList KConfigGroup::keyList() const 01270 { 01271 Q_ASSERT_X(isValid(), "KConfigGroup::keyList", "accessing an invalid group"); 01272 01273 return entryMap().keys(); 01274 } 01275 01276 void KConfigGroup::markAsClean() 01277 { 01278 Q_ASSERT_X(isValid(), "KConfigGroup::markAsClean", "accessing an invalid group"); 01279 01280 config()->markAsClean(); 01281 } 01282 01283 KConfigGroup::AccessMode KConfigGroup::accessMode() const 01284 { 01285 Q_ASSERT_X(isValid(), "KConfigGroup::accessMode", "accessing an invalid group"); 01286 01287 return config()->accessMode(); 01288 } 01289 01290 bool KConfigGroup::hasGroupImpl(const QByteArray & b) const 01291 { 01292 Q_ASSERT_X(isValid(), "KConfigGroup::hasGroupImpl", "accessing an invalid group"); 01293 01294 return config()->hasGroup(d->fullName(b)); 01295 } 01296 01297 void KConfigGroup::deleteGroupImpl(const QByteArray &b, WriteConfigFlags flags) 01298 { 01299 Q_ASSERT_X(isValid(), "KConfigGroup::deleteGroupImpl", "accessing an invalid group"); 01300 Q_ASSERT_X(!d->bConst,"KConfigGroup::deleteGroupImpl", "deleting from a read-only group"); 01301 01302 config()->deleteGroup(d->fullName(b), flags); 01303 } 01304 01305 bool KConfigGroup::isGroupImmutableImpl(const QByteArray& b) const 01306 { 01307 Q_ASSERT_X(isValid(), "KConfigGroup::isGroupImmutableImpl", "accessing an invalid group"); 01308 01309 if (!hasGroupImpl(b)) // group doesn't exist yet 01310 return d->bImmutable; // child groups are immutable if the parent is immutable. 01311 01312 return config()->isGroupImmutable(d->fullName(b)); 01313 } 01314 01315 void KConfigGroup::copyTo(KConfigBase* other, WriteConfigFlags pFlags) const 01316 { 01317 Q_ASSERT_X(isValid(), "KConfigGroup::copyTo", "accessing an invalid group"); 01318 Q_ASSERT(other != 0); 01319 01320 if (KConfigGroup *otherGroup = dynamic_cast<KConfigGroup*>(other)) { 01321 config()->d_func()->copyGroup(d->fullName(), otherGroup->d->fullName(), otherGroup, pFlags); 01322 } else if (KConfig* otherConfig = dynamic_cast<KConfig*>(other)) { 01323 KConfigGroup newGroup = otherConfig->group(d->fullName()); 01324 otherConfig->d_func()->copyGroup(d->fullName(), d->fullName(), &newGroup, pFlags); 01325 } else { 01326 Q_ASSERT_X(false, "KConfigGroup::copyTo", "unknown type of KConfigBase"); 01327 } 01328 } 01329 01330 void KConfigGroup::reparent(KConfigBase* parent, WriteConfigFlags pFlags) 01331 { 01332 Q_ASSERT_X(isValid(), "KConfigGroup::reparent", "accessing an invalid group"); 01333 Q_ASSERT_X(!d->bConst, "KConfigGroup::reparent", "reparenting a read-only group"); 01334 Q_ASSERT_X(!d->bImmutable, "KConfigGroup::reparent", "reparenting an immutable group"); 01335 Q_ASSERT(parent != 0); 01336 01337 KConfigGroup oldGroup(*this); 01338 01339 d = KConfigGroupPrivate::create(parent, d->mName, false, false); 01340 oldGroup.copyTo(this, pFlags); 01341 oldGroup.deleteGroup(); // so that the entries with the old group name are deleted on sync 01342 }
KDE 4.6 API Reference