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

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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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