• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

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

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.6
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal