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