kconfigbase.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /*
00003    This file is part of the KDE libraries
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 <cstdio>
00024 #include <cstdlib>
00025 
00026 #include <qfile.h>
00027 #include <qdir.h>
00028 #include <qtextstream.h>
00029 #include <qtextcodec.h>
00030 #include <qdom.h>
00031 
00032 #include <kapplication.h>
00033 #include <kglobal.h>
00034 #include <klocale.h>
00035 #include <kcharsets.h>
00036 
00037 #include "kconfigbase.h"
00038 #include "kconfigbackend.h"
00039 #include "kdebug.h"
00040 #include "kstandarddirs.h"
00041 #include "kstringhandler.h"
00042 
00043 void KConfigBase::dumpConfig( const QString& ent, const QString& val, const QString& type ) const 
00044 {
00045    bool dumpEnabled = getenv( "DUMPCONFIG" ) ? true : false;
00046 
00047    if( backEnd == 0 )
00048    {
00049       dumpEnabled = false;
00050       return;
00051    }
00052    else if( !dumpEnabled )
00053       return;
00054 
00055    QString filename;
00056    filename = backEnd->fileName();
00057 
00058    // blacklists some entries to avoid uselless queries
00059    if (  filename == "kdebugrc"
00060          || filename == "kconf_updaterc"
00061          || filename == "kdedrc"
00062          || filename == "klauncherrc"
00063          || filename == "kdeinitrc"
00064          || filename == "kbuildsycocarc"
00065          || filename == "drkonqirc"
00066          || filename.startsWith( "/" )
00067          || filename.endsWith( ".desktop" )
00068          )
00069       return;
00070    
00071    QDomDocument *xmldoc;
00072    QDomDocument *globalxmldoc;
00073   
00074    bool globalgroup = false;
00075    
00076    if ( mGroup == "KDE" || mGroup == "General" )
00077       globalgroup = true;
00078 
00079    QDomElement root;
00080    QDir bd( getenv( "KCONFIGXMLDIR" ) );
00081    
00082    QString data = bd.exists() ? bd.absPath() : "/tmp";
00083    QString localfile = data + '/' + filename + ".xml"; 
00084    QFile file( localfile );
00085    if ( !file.open( IO_ReadOnly ) )
00086    {
00087       xmldoc = new QDomDocument( filename );
00088       root = xmldoc->createElement( filename );
00089       xmldoc->appendChild( root );
00090    }
00091    else
00092    {
00093       xmldoc = new QDomDocument();
00094       if ( !xmldoc->setContent( &file ) ) 
00095       {
00096          file.close();
00097          return;
00098       }
00099       root = xmldoc->documentElement();
00100    }
00101    file.close();
00102    
00103    QDomElement globalroot;
00104    localfile = data + "/kdeglobals.xml"; 
00105    file.setName( localfile );
00106    if ( !file.open( IO_ReadOnly ) )
00107    {
00108       globalxmldoc = new QDomDocument( "kdeglobals" );
00109       globalroot = globalxmldoc->createElement( "kdeglobals" );
00110       globalxmldoc->appendChild( globalroot );
00111    }
00112    else
00113    {
00114       globalxmldoc = new QDomDocument();
00115       if ( !globalxmldoc->setContent( &file ) ) 
00116       {
00117          file.close();
00118          return;
00119       }
00120       globalroot = globalxmldoc->documentElement(); 
00121    }
00122    file.close();
00123    
00124 
00125    bool exists = false;
00126 
00127    QDomNode node;
00128    QDomElement grp;
00129 
00130    if( ! globalgroup )
00131    {
00132       node = xmldoc->documentElement().namedItem( "group" );
00133       while ( !node.isNull() )
00134       {
00135          QString current = node.attributes().item( 0 ).nodeValue();
00136          if ( node.attributes().item( 0 ).nodeValue() == QString( mGroup ) )
00137          {
00138             grp = node.toElement();
00139             exists = true;
00140             break;
00141          }
00142          node = node.nextSibling();
00143       }
00144       
00145       if ( ! exists )
00146       {
00147          grp = xmldoc->createElement( "group" );
00148          grp.setAttribute( "name", mGroup ); 
00149          root.appendChild( grp );
00150       }
00151    }
00152    else
00153    {
00154        node = globalxmldoc->documentElement().namedItem( "group" );
00155       while ( !node.isNull() )
00156       {
00157          QString current = node.attributes().item( 0 ).nodeValue();
00158          if ( node.attributes().item( 0 ).nodeValue() == QString( mGroup ) )
00159          {
00160             grp = node.toElement();
00161             exists = true;
00162             break;
00163          }
00164          node = node.nextSibling();
00165       }
00166       
00167       if ( ! exists )
00168       {
00169          grp = globalxmldoc->createElement( "group" );
00170          grp.setAttribute( "name", mGroup ); 
00171          globalroot.appendChild( grp );
00172       }
00173    }
00174 
00175      
00176    exists = false;
00177    QDomElement entry;
00178    QDomText t;
00179    if ( ! globalgroup )
00180       t = xmldoc->createTextNode( val );
00181    else
00182       t = globalxmldoc->createTextNode( val );
00183    node = grp.namedItem( "property" );
00184 
00185    while ( !node.isNull() )
00186    {
00187       QString current = node.attributes().item( 0 ).nodeValue();
00188       if ( node.attributes().namedItem( "name" ).nodeValue() == ent )
00189       {
00190          entry = node.toElement();
00191          exists = true;
00192          break;
00193       }
00194       node = node.nextSibling();
00195    }
00196    
00197    if ( ! exists )
00198    {
00199 
00200       if ( ! globalgroup )
00201          entry = xmldoc->createElement( "property" );
00202       else
00203          entry = globalxmldoc->createElement( "property" );
00204       entry.setAttribute( "name", ent );
00205       entry.setAttribute( "type", type );
00206       grp.appendChild( entry );
00207       entry.appendChild( t );
00208    }
00209 
00210    // Save every time to avoid duplicated root elements
00211    filename = data + '/' + backEnd->fileName() + ".xml"; 
00212    file.setName( filename );
00213    if ( file.open( IO_WriteOnly ) ) 
00214    {
00215       QTextStream qualquer( &file );
00216       qualquer <<  xmldoc->toString() << endl;
00217       file.close();
00218    }
00219    
00220    filename = data + "/kdeglobals.xml"; 
00221    file.setName( filename );
00222    if ( file.open( IO_WriteOnly ) ) 
00223    {
00224       QTextStream qualquer( &file );
00225       qualquer <<  globalxmldoc->toString() << endl;
00226       file.close();
00227    }
00228 
00229 }
00230 
00231 KConfigBase::KConfigBase()
00232   : backEnd(0L), bDirty(false), bLocaleInitialized(false),
00233     bReadOnly(false), bExpand(false), m_Private(0)
00234 {
00235     m_Private = m_Private = new KConfigBasePrivate();
00236     m_Private->backEnds.setAutoDelete(true);
00237     setGroup(QString::null);
00238 }
00239 
00240 KConfigBase::~KConfigBase()
00241 {
00242 
00243    delete m_Private;
00244 }
00245 
00246 void KConfigBase::setLocale()
00247 {
00248   bLocaleInitialized = true;
00249 
00250   if (KGlobal::locale())
00251     aLocaleString = KGlobal::locale()->language().utf8();
00252   else
00253     aLocaleString = KLocale::defaultLanguage().utf8();
00254   if (backEnd)
00255      backEnd->setLocaleString(aLocaleString);
00256 }
00257 
00258 QString KConfigBase::locale() const
00259 {
00260   return QString::fromUtf8(aLocaleString);
00261 }
00262 
00263 void KConfigBase::setGroup( const QString& group )
00264 {
00265   if ( group.isEmpty() )
00266     mGroup = "<default>";
00267   else
00268     mGroup = group.utf8();
00269 }
00270 
00271 void KConfigBase::setGroup( const char *pGroup )
00272 {
00273   setGroup(QCString(pGroup));
00274 }
00275 
00276 void KConfigBase::setGroup( const QCString &group )
00277 {
00278   if ( group.isEmpty() )
00279     mGroup = "<default>";
00280   else
00281     mGroup = group;
00282 }
00283 
00284 QString KConfigBase::group() const {
00285   return QString::fromUtf8(mGroup);
00286 }
00287 
00288 void KConfigBase::setDesktopGroup()
00289 {
00290   mGroup = "Desktop Entry";
00291 }
00292 
00293 bool KConfigBase::hasKey(const QString &key) const
00294 {
00295    return hasKey(key.utf8().data());
00296 }
00297 
00298 bool KConfigBase::hasKey(const char *pKey) const
00299 {
00300   KEntryKey aEntryKey(mGroup, 0);
00301   aEntryKey.c_key = pKey;
00302   aEntryKey.bDefault = readDefaults();
00303 
00304   if (!locale().isNull()) {
00305     // try the localized key first
00306     aEntryKey.bLocal = true;
00307     KEntry entry = lookupData(aEntryKey);
00308     if (!entry.mValue.isNull())
00309        return true;
00310     aEntryKey.bLocal = false;
00311   }
00312 
00313   // try the non-localized version
00314   KEntry entry = lookupData(aEntryKey);
00315   return !entry.mValue.isNull();
00316 }
00317 
00318 bool KConfigBase::hasGroup(const QString &group) const
00319 {
00320   return internalHasGroup( group.utf8());
00321 }
00322 
00323 bool KConfigBase::hasGroup(const char *_pGroup) const
00324 {
00325   return internalHasGroup( QCString(_pGroup));
00326 }
00327 
00328 bool KConfigBase::hasGroup(const QCString &_pGroup) const
00329 {
00330   return internalHasGroup( _pGroup);
00331 }
00332 
00333 bool KConfigBase::isImmutable() const
00334 {
00335   return (getConfigState() != ReadWrite);
00336 }
00337 
00338 bool KConfigBase::groupIsImmutable(const QString &group) const
00339 {
00340   if (getConfigState() != ReadWrite)
00341      return true;
00342 
00343   KEntryKey groupKey(group.utf8(), 0);
00344   KEntry entry = lookupData(groupKey);
00345   return entry.bImmutable;
00346 }
00347 
00348 bool KConfigBase::entryIsImmutable(const QString &key) const
00349 {
00350   if (getConfigState() != ReadWrite)
00351      return true;
00352 
00353   KEntryKey entryKey(mGroup, 0);
00354   KEntry aEntryData = lookupData(entryKey); // Group
00355   if (aEntryData.bImmutable)
00356     return true;
00357 
00358   QCString utf8_key = key.utf8();
00359   entryKey.c_key = utf8_key.data();
00360   aEntryData = lookupData(entryKey); // Normal entry
00361   if (aEntryData.bImmutable)
00362     return true;
00363 
00364   entryKey.bLocal = true;
00365   aEntryData = lookupData(entryKey); // Localized entry
00366   return aEntryData.bImmutable;
00367 }
00368 
00369 
00370 QString KConfigBase::readEntryUntranslated( const QString& pKey,
00371                                 const QString& aDefault ) const
00372 {
00373    return KConfigBase::readEntryUntranslated(pKey.utf8().data(), aDefault);
00374 }
00375 
00376 
00377 QString KConfigBase::readEntryUntranslated( const char *pKey,
00378                                 const QString& aDefault ) const
00379 {
00380    QCString result = readEntryUtf8(pKey);
00381    if (result.isNull())
00382       return aDefault;
00383    return QString::fromUtf8(result);
00384 }
00385 
00386 
00387 QString KConfigBase::readEntry( const QString& pKey,
00388                                 const QString& aDefault ) const
00389 {
00390    QString aValue = KConfigBase::readEntry(pKey.utf8().data(), aDefault);
00391    if ( ! aValue.isNull() )
00392       dumpConfig( pKey, aValue, "String" );
00393    return aValue;
00394 }
00395 
00396 QString KConfigBase::readEntry( const char *pKey,
00397                                 const QString& aDefault ) const
00398 {
00399   // we need to access _locale instead of the method locale()
00400   // because calling locale() will create a locale object if it
00401   // doesn't exist, which requires KConfig, which will create a infinite
00402   // loop, and nobody likes those.
00403   if (!bLocaleInitialized && KGlobal::_locale) {
00404     // get around const'ness.
00405     KConfigBase *that = const_cast<KConfigBase *>(this);
00406     that->setLocale();
00407   }
00408 
00409   QString aValue;
00410 
00411   bool expand = false;
00412   // construct a localized version of the key
00413   // try the localized key first
00414   KEntry aEntryData;
00415   KEntryKey entryKey(mGroup, 0);
00416   entryKey.c_key = pKey;
00417   entryKey.bDefault = readDefaults();
00418   entryKey.bLocal = true;
00419   aEntryData = lookupData(entryKey);
00420   if (!aEntryData.mValue.isNull()) {
00421     // for GNOME .desktop
00422     aValue = KStringHandler::from8Bit( aEntryData.mValue.data() );
00423     expand = aEntryData.bExpand;
00424   } else {
00425     entryKey.bLocal = false;
00426     aEntryData = lookupData(entryKey);
00427     if (!aEntryData.mValue.isNull()) {
00428       aValue = QString::fromUtf8(aEntryData.mValue.data());
00429       if (aValue.isNull())
00430       {
00431         static const QString &emptyString = KGlobal::staticQString("");
00432         aValue = emptyString;
00433       }
00434       expand = aEntryData.bExpand;
00435     } else {
00436       aValue = aDefault;
00437     }
00438   }
00439 
00440   // only do dollar expansion if so desired
00441   if( expand || bExpand )
00442     {
00443       // check for environment variables and make necessary translations
00444       int nDollarPos = aValue.find( '$' );
00445 
00446       while( nDollarPos != -1 && nDollarPos+1 < static_cast<int>(aValue.length())) {
00447         // there is at least one $
00448         if( (aValue)[nDollarPos+1] == '(' ) {
00449           uint nEndPos = nDollarPos+1;
00450           // the next character is no $
00451           while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!=')') )
00452               nEndPos++;
00453           nEndPos++;
00454           QString cmd = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 );
00455 
00456           QString result;
00457           FILE *fs = popen(QFile::encodeName(cmd).data(), "r");
00458           if (fs)
00459           {
00460              {
00461              QTextStream ts(fs, IO_ReadOnly);
00462              result = ts.read().stripWhiteSpace();
00463              }
00464              pclose(fs);
00465           }
00466           aValue.replace( nDollarPos, nEndPos-nDollarPos, result );
00467         } else if( (aValue)[nDollarPos+1] != '$' ) {
00468           uint nEndPos = nDollarPos+1;
00469           // the next character is no $
00470           QString aVarName;
00471           if (aValue[nEndPos]=='{')
00472           {
00473             while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!='}') )
00474                 nEndPos++;
00475             nEndPos++;
00476             aVarName = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 );
00477           }
00478           else
00479           {
00480             while ( nEndPos <= aValue.length() && (aValue[nEndPos].isNumber()
00481                     || aValue[nEndPos].isLetter() || aValue[nEndPos]=='_' )  )
00482                 nEndPos++;
00483             aVarName = aValue.mid( nDollarPos+1, nEndPos-nDollarPos-1 );
00484           }
00485           const char* pEnv = 0;
00486           if (!aVarName.isEmpty())
00487                pEnv = getenv( aVarName.ascii() );
00488           if( pEnv ) {
00489         // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!!
00490         // A environment variables may contain values in 8bit
00491         // locale cpecified encoding or in UTF8 encoding.
00492         aValue.replace( nDollarPos, nEndPos-nDollarPos, KStringHandler::from8Bit( pEnv ) );
00493           } else
00494             aValue.remove( nDollarPos, nEndPos-nDollarPos );
00495         } else {
00496           // remove one of the dollar signs
00497           aValue.remove( nDollarPos, 1 );
00498           nDollarPos++;
00499         }
00500         nDollarPos = aValue.find( '$', nDollarPos );
00501       }
00502     }
00503  
00504   return aValue;
00505 }
00506 
00507 QCString KConfigBase::readEntryUtf8( const char *pKey) const
00508 {
00509   // We don't try the localized key
00510   KEntryKey entryKey(mGroup, 0);
00511   entryKey.bDefault = readDefaults();
00512   entryKey.c_key = pKey;
00513   KEntry aEntryData = lookupData(entryKey);
00514   if (aEntryData.bExpand)
00515   {
00516      // We need to do fancy, take the slow route.
00517      return readEntry(pKey, QString::null).utf8();
00518   }
00519   return aEntryData.mValue;
00520 }
00521 
00522 QVariant KConfigBase::readPropertyEntry( const QString& pKey,
00523                                           QVariant::Type type ) const
00524 {
00525   return readPropertyEntry(pKey.utf8().data(), type);
00526 }
00527 
00528 QVariant KConfigBase::readPropertyEntry( const char *pKey,
00529                                           QVariant::Type type ) const
00530 {
00531   QVariant va;
00532   if ( !hasKey( pKey ) ) return va;
00533   (void)va.cast(type);
00534   return readPropertyEntry(pKey, va);
00535 }
00536 
00537 QVariant KConfigBase::readPropertyEntry( const QString& pKey,
00538                                          const QVariant &aDefault ) const
00539 {
00540   return readPropertyEntry(pKey.utf8().data(), aDefault);
00541 }
00542 
00543 QVariant KConfigBase::readPropertyEntry( const char *pKey,
00544                                          const QVariant &aDefault ) const
00545 {
00546   if ( !hasKey( pKey ) ) return aDefault;
00547 
00548   QVariant tmp = aDefault;
00549 
00550   switch( aDefault.type() )
00551   {
00552       case QVariant::Invalid:
00553           return QVariant();
00554       case QVariant::String:
00555           return QVariant( readEntry( pKey, aDefault.toString() ) );
00556       case QVariant::StringList:
00557           return QVariant( readListEntry( pKey ) );
00558       case QVariant::List: {
00559           QStringList strList = readListEntry( pKey );
00560           QStringList::ConstIterator it = strList.begin();
00561           QStringList::ConstIterator end = strList.end();
00562           QValueList<QVariant> list;
00563 
00564           for (; it != end; ++it ) {
00565               tmp = *it;
00566               list.append( tmp );
00567           }
00568           return QVariant( list );
00569       }
00570       case QVariant::Font:
00571           return QVariant( readFontEntry( pKey, &tmp.asFont() ) );
00572       case QVariant::Point:
00573           return QVariant( readPointEntry( pKey, &tmp.asPoint() ) );
00574       case QVariant::Rect:
00575           return QVariant( readRectEntry( pKey, &tmp.asRect() ) );
00576       case QVariant::Size:
00577           return QVariant( readSizeEntry( pKey, &tmp.asSize() ) );
00578       case QVariant::Color:
00579           return QVariant( readColorEntry( pKey, &tmp.asColor() ) );
00580       case QVariant::Int:
00581           return QVariant( readNumEntry( pKey, aDefault.toInt() ) );
00582       case QVariant::UInt:
00583           return QVariant( readUnsignedNumEntry( pKey, aDefault.toUInt() ) );
00584       case QVariant::LongLong:
00585           return QVariant( readNum64Entry( pKey, aDefault.toLongLong() ) );
00586       case QVariant::ULongLong:
00587           return QVariant( readUnsignedNum64Entry( pKey, aDefault.toULongLong() ) );
00588       case QVariant::Bool:
00589           return QVariant( readBoolEntry( pKey, aDefault.toBool() ), 0 );
00590       case QVariant::Double:
00591           return QVariant( readDoubleNumEntry( pKey, aDefault.toDouble() ) );
00592       case QVariant::DateTime:
00593           return QVariant( readDateTimeEntry( pKey, &tmp.asDateTime() ) );
00594       case QVariant::Date:
00595           return QVariant(readDateTimeEntry( pKey, &tmp.asDateTime() ).date());
00596 
00597       case QVariant::Pixmap:
00598       case QVariant::Image:
00599       case QVariant::Brush:
00600       case QVariant::Palette:
00601       case QVariant::ColorGroup:
00602       case QVariant::Map:
00603       case QVariant::IconSet:
00604       case QVariant::CString:
00605       case QVariant::PointArray:
00606       case QVariant::Region:
00607       case QVariant::Bitmap:
00608       case QVariant::Cursor:
00609       case QVariant::SizePolicy:
00610       case QVariant::Time:
00611       case QVariant::ByteArray:
00612       case QVariant::BitArray:
00613       case QVariant::KeySequence:
00614       case QVariant::Pen:
00615           break;
00616   }
00617 
00618   Q_ASSERT( 0 );
00619   return QVariant();
00620 }
00621 
00622 int KConfigBase::readListEntry( const QString& pKey,
00623                                 QStrList &list, char sep ) const
00624 {
00625   return readListEntry(pKey.utf8().data(), list, sep);
00626 }
00627 
00628 int KConfigBase::readListEntry( const char *pKey,
00629                                 QStrList &list, char sep ) const
00630 {
00631   if( !hasKey( pKey ) )
00632   {
00633     return 0;
00634   }
00635 
00636   QCString str_list = readEntryUtf8( pKey );
00637   if (str_list.isEmpty())
00638     return 0;
00639 
00640   list.clear();
00641   QCString value = "";
00642   int len = str_list.length();
00643 
00644   for (int i = 0; i < len; i++) {
00645     if (str_list[i] != sep && str_list[i] != '\\') {
00646       value += str_list[i];
00647       continue;
00648     }
00649     if (str_list[i] == '\\') {
00650       i++;
00651       if ( i < len )
00652         value += str_list[i];
00653       continue;
00654     }
00655     // if we fell through to here, we are at a separator.  Append
00656     // contents of value to the list
00657     // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!!
00658     // A QStrList may contain values in 8bit locale cpecified
00659     // encoding
00660     list.append( value );
00661     value.truncate(0);
00662   }
00663 
00664   if ( str_list[len-1] != sep || ( len > 1 && str_list[len-2] == '\\' ) )
00665     list.append( value );
00666   return list.count();
00667 }
00668 
00669 QStringList KConfigBase::readListEntry( const QString& pKey, char sep ) const
00670 {
00671   return readListEntry(pKey.utf8().data(), sep);
00672 }
00673 
00674 QStringList KConfigBase::readListEntry( const char *pKey, char sep ) const
00675 {
00676   static const QString& emptyString = KGlobal::staticQString("");
00677 
00678   QStringList list;
00679   if( !hasKey( pKey ) )
00680   {
00681     return list;
00682   }
00683   QString str_list = readEntry( pKey );
00684   if( str_list.isEmpty() )
00685     return list;
00686   QString value(emptyString);
00687   int len = str_list.length();
00688  // obviously too big, but faster than letting each += resize the string.
00689   value.reserve( len );
00690   for( int i = 0; i < len; i++ )
00691     {
00692       if( str_list[i] != sep && str_list[i] != '\\' )
00693         {
00694           value += str_list[i];
00695           continue;
00696         }
00697       if( str_list[i] == '\\' )
00698         {
00699           i++;
00700           if ( i < len )
00701             value += str_list[i];
00702           continue;
00703         }
00704       QString finalvalue( value );
00705       finalvalue.squeeze();
00706       list.append( finalvalue );
00707       value.truncate( 0 );
00708     }
00709   if ( str_list[len-1] != sep || ( len > 1 && str_list[len-2] == '\\' ) )
00710   {
00711     value.squeeze();
00712     list.append( value );
00713   }
00714   dumpConfig( pKey, list.join( "," ), "List" );
00715   return list;
00716 }
00717 
00718 QStringList KConfigBase::readListEntry( const char* pKey, const QStringList& aDefault,
00719         char sep ) const
00720 {
00721     if ( !hasKey( pKey ) )
00722    {
00723         return aDefault;
00724    }
00725     else
00726         return readListEntry( pKey, sep );
00727 }
00728 
00729 QValueList<int> KConfigBase::readIntListEntry( const QString& pKey ) const
00730 {
00731   return readIntListEntry(pKey.utf8().data());
00732 }
00733 
00734 QValueList<int> KConfigBase::readIntListEntry( const char *pKey ) const
00735 {
00736   QStringList strlist = readListEntry(pKey);
00737   dumpConfig( pKey, strlist.join( "," ), "IntList" );
00738 
00739   QValueList<int> list;
00740   QStringList::ConstIterator end(strlist.end());
00741   for (QStringList::ConstIterator it = strlist.begin(); it != end; ++it)
00742     // I do not check if the toInt failed because I consider the number of items
00743     // more important than their value
00744     list << (*it).toInt();
00745 
00746   return list;
00747 }
00748 
00749 QString KConfigBase::readPathEntry( const QString& pKey, const QString& pDefault ) const
00750 {
00751   return readPathEntry(pKey.utf8().data(), pDefault);
00752 }
00753 
00754 QString KConfigBase::readPathEntry( const char *pKey, const QString& pDefault ) const
00755 {
00756   const bool bExpandSave = bExpand;
00757   bExpand = true;
00758   QString aValue = readEntry( pKey, pDefault );
00759   dumpConfig( pKey, aValue, "Path" );
00760   bExpand = bExpandSave;
00761   return aValue;
00762 }
00763 
00764 QStringList KConfigBase::readPathListEntry( const QString& pKey, char sep ) const
00765 {
00766   return readPathListEntry(pKey.utf8().data(), sep);
00767 }
00768 
00769 QStringList KConfigBase::readPathListEntry( const char *pKey, char sep ) const
00770 {
00771   const bool bExpandSave = bExpand;
00772   bExpand = true;
00773   QStringList aValue = readListEntry( pKey, sep );
00774 
00775   dumpConfig( pKey, aValue.join( "," ), "PathList" );
00776   bExpand = bExpandSave;
00777   return aValue;
00778 }
00779 
00780 int KConfigBase::readNumEntry( const QString& pKey, int nDefault) const
00781 {
00782   return readNumEntry(pKey.utf8().data(), nDefault);
00783 }
00784 
00785 int KConfigBase::readNumEntry( const char *pKey, int nDefault) const
00786 {
00787   dumpConfig( pKey, QString::number( nDefault ), "Num" );
00788   QCString aValue = readEntryUtf8( pKey );
00789   if( aValue.isNull() )
00790     return nDefault;
00791   else if( aValue == "true" || aValue == "on" || aValue == "yes" )
00792     return 1;
00793   else
00794     {
00795       bool ok;
00796       int rc = aValue.toInt( &ok );
00797       return( ok ? rc : nDefault );
00798     }
00799 }
00800 
00801 
00802 unsigned int KConfigBase::readUnsignedNumEntry( const QString& pKey, unsigned int nDefault) const
00803 {
00804   return readUnsignedNumEntry(pKey.utf8().data(), nDefault);
00805 }
00806 
00807 unsigned int KConfigBase::readUnsignedNumEntry( const char *pKey, unsigned int nDefault) const
00808 {
00809   dumpConfig( pKey, QString::number( nDefault ), "UnsignedNum" );
00810   QCString aValue = readEntryUtf8( pKey );
00811   if( aValue.isNull() )
00812     return nDefault;
00813   else
00814     {
00815       bool ok;
00816       unsigned int rc = aValue.toUInt( &ok );
00817       return( ok ? rc : nDefault );
00818     }
00819 }
00820 
00821 
00822 long KConfigBase::readLongNumEntry( const QString& pKey, long nDefault) const
00823 {
00824   return readLongNumEntry(pKey.utf8().data(), nDefault);
00825 }
00826 
00827 long KConfigBase::readLongNumEntry( const char *pKey, long nDefault) const
00828 {
00829   dumpConfig( pKey, QString::number( nDefault ), "LongNum" );
00830   QCString aValue = readEntryUtf8( pKey );
00831   if( aValue.isNull() )
00832     return nDefault;
00833   else
00834     {
00835       bool ok;
00836       long rc = aValue.toLong( &ok );
00837       return( ok ? rc : nDefault );
00838     }
00839 }
00840 
00841 
00842 unsigned long KConfigBase::readUnsignedLongNumEntry( const QString& pKey, unsigned long nDefault) const
00843 {
00844   return readUnsignedLongNumEntry(pKey.utf8().data(), nDefault);
00845 }
00846 
00847 unsigned long KConfigBase::readUnsignedLongNumEntry( const char *pKey, unsigned long nDefault) const
00848 {
00849   dumpConfig( pKey, QString::number( nDefault ), "UnsignedLongNum" );
00850   QCString aValue = readEntryUtf8( pKey );
00851   if( aValue.isNull() )
00852     return nDefault;
00853   else
00854     {
00855       bool ok;
00856       unsigned long rc = aValue.toULong( &ok );
00857       return( ok ? rc : nDefault );
00858     }
00859 }
00860 
00861 Q_INT64 KConfigBase::readNum64Entry( const QString& pKey, Q_INT64 nDefault) const
00862 {
00863   return readNum64Entry(pKey.utf8().data(), nDefault);
00864 }
00865 
00866 Q_INT64 KConfigBase::readNum64Entry( const char *pKey, Q_INT64 nDefault) const
00867 {
00868   dumpConfig( pKey, QString::number( nDefault ), "Num64" );
00869   // Note that QCString::toLongLong() is missing, we muse use a QString instead.
00870   QString aValue = readEntry( pKey );
00871   if( aValue.isNull() )
00872     return nDefault;
00873   else
00874     {
00875       bool ok;
00876       Q_INT64 rc = aValue.toLongLong( &ok );
00877       return( ok ? rc : nDefault );
00878     }
00879 }
00880 
00881 
00882 Q_UINT64 KConfigBase::readUnsignedNum64Entry( const QString& pKey, Q_UINT64 nDefault) const
00883 {
00884   return readUnsignedNum64Entry(pKey.utf8().data(), nDefault);
00885 }
00886 
00887 Q_UINT64 KConfigBase::readUnsignedNum64Entry( const char *pKey, Q_UINT64 nDefault) const
00888 {
00889   dumpConfig( pKey, QString::number( nDefault ), "UnsignedNum64" );
00890   // Note that QCString::toULongLong() is missing, we muse use a QString instead.
00891   QString aValue = readEntry( pKey );
00892   if( aValue.isNull() )
00893     return nDefault;
00894   else
00895     {
00896       bool ok;
00897       Q_UINT64 rc = aValue.toULongLong( &ok );
00898       return( ok ? rc : nDefault );
00899     }
00900 }
00901 
00902 double KConfigBase::readDoubleNumEntry( const QString& pKey, double nDefault) const
00903 {
00904   return readDoubleNumEntry(pKey.utf8().data(), nDefault);
00905 }
00906 
00907 double KConfigBase::readDoubleNumEntry( const char *pKey, double nDefault) const
00908 {
00909   dumpConfig( pKey, QString::number( nDefault ), "Double" );
00910   
00911   QCString aValue = readEntryUtf8( pKey );
00912   if( aValue.isNull() )
00913     return nDefault;
00914   else
00915     {
00916       bool ok;
00917       double rc = aValue.toDouble( &ok );
00918       return( ok ? rc : nDefault );
00919     }
00920 }
00921 
00922 
00923 bool KConfigBase::readBoolEntry( const QString& pKey, bool bDefault ) const
00924 {
00925    return readBoolEntry(pKey.utf8().data(), bDefault);
00926 }
00927 
00928 bool KConfigBase::readBoolEntry( const char *pKey, bool bDefault ) const
00929 {
00930   dumpConfig( pKey, QString::number( bDefault ), "Bool" );
00931 
00932   QCString aValue = readEntryUtf8( pKey );
00933 
00934   if( aValue.isNull() )
00935     return bDefault;
00936   else
00937     {
00938       if( aValue == "true" || aValue == "on" || aValue == "yes" || aValue == "1" )
00939         return true;
00940       else
00941         {
00942           bool bOK;
00943           int val = aValue.toInt( &bOK );
00944           if( bOK && val != 0 )
00945             return true;
00946           else
00947             return false;
00948         }
00949     }
00950 }
00951 
00952 QFont KConfigBase::readFontEntry( const QString& pKey, const QFont* pDefault ) const
00953 {
00954   return readFontEntry(pKey.utf8().data(), pDefault);
00955 }
00956 
00957 QFont KConfigBase::readFontEntry( const char *pKey, const QFont* pDefault ) const
00958 {
00959    if ( pDefault )
00960       dumpConfig( pKey, pDefault->toString(), "Font" );
00961    else
00962       dumpConfig( pKey, "", "Font" );
00963 
00964   QFont aRetFont;
00965 
00966   QString aValue = readEntry( pKey );
00967   if( !aValue.isNull() ) {
00968     if ( aValue.contains( ',' ) > 5 ) {
00969       // KDE3 and upwards entry
00970       if ( !aRetFont.fromString( aValue ) && pDefault )
00971         aRetFont = *pDefault;
00972     }
00973     else {
00974       // backward compatibility with older font formats
00975       // ### remove KDE 3.1 ?
00976       // find first part (font family)
00977       int nIndex = aValue.find( ',' );
00978       if( nIndex == -1 ){
00979         if( pDefault )
00980           aRetFont = *pDefault;
00981         return aRetFont;
00982       }
00983       aRetFont.setFamily( aValue.left( nIndex ) );
00984 
00985       // find second part (point size)
00986       int nOldIndex = nIndex;
00987       nIndex = aValue.find( ',', nOldIndex+1 );
00988       if( nIndex == -1 ){
00989         if( pDefault )
00990           aRetFont = *pDefault;
00991         return aRetFont;
00992       }
00993 
00994       aRetFont.setPointSize( aValue.mid( nOldIndex+1,
00995                                          nIndex-nOldIndex-1 ).toInt() );
00996 
00997       // find third part (style hint)
00998       nOldIndex = nIndex;
00999       nIndex = aValue.find( ',', nOldIndex+1 );
01000 
01001       if( nIndex == -1 ){
01002         if( pDefault )
01003           aRetFont = *pDefault;
01004         return aRetFont;
01005       }
01006 
01007       aRetFont.setStyleHint( (QFont::StyleHint)aValue.mid( nOldIndex+1, nIndex-nOldIndex-1 ).toUInt() );
01008 
01009       // find fourth part (char set)
01010       nOldIndex = nIndex;
01011       nIndex = aValue.find( ',', nOldIndex+1 );
01012 
01013       if( nIndex == -1 ){
01014         if( pDefault )
01015           aRetFont = *pDefault;
01016         return aRetFont;
01017       }
01018 
01019       QString chStr=aValue.mid( nOldIndex+1,
01020                                 nIndex-nOldIndex-1 );
01021       // find fifth part (weight)
01022       nOldIndex = nIndex;
01023       nIndex = aValue.find( ',', nOldIndex+1 );
01024 
01025       if( nIndex == -1 ){
01026         if( pDefault )
01027           aRetFont = *pDefault;
01028         return aRetFont;
01029       }
01030 
01031       aRetFont.setWeight( aValue.mid( nOldIndex+1,
01032                                       nIndex-nOldIndex-1 ).toUInt() );
01033 
01034       // find sixth part (font bits)
01035       uint nFontBits = aValue.right( aValue.length()-nIndex-1 ).toUInt();
01036 
01037       aRetFont.setItalic( nFontBits & 0x01 );
01038       aRetFont.setUnderline( nFontBits & 0x02 );
01039       aRetFont.setStrikeOut( nFontBits & 0x04 );
01040       aRetFont.setFixedPitch( nFontBits & 0x08 );
01041       aRetFont.setRawMode( nFontBits & 0x20 );
01042     }
01043   }
01044   else
01045     {
01046       if( pDefault )
01047         aRetFont = *pDefault;
01048     }
01049 
01050   return aRetFont;
01051 }
01052 
01053 
01054 QRect KConfigBase::readRectEntry( const QString& pKey, const QRect* pDefault ) const
01055 {
01056   return readRectEntry(pKey.utf8().data(), pDefault);
01057 }
01058 
01059 QRect KConfigBase::readRectEntry( const char *pKey, const QRect* pDefault ) const
01060 {
01061    if ( pDefault )
01062       dumpConfig( pKey, QString::number( pDefault->left() ) + "," + 
01063             QString::number( pDefault->top() ) + "," + 
01064             QString::number( pDefault->right() ) + "," +
01065             QString::number( pDefault->bottom() ), 
01066             "Rect" );
01067    else
01068       dumpConfig( pKey, "", "Rect" );
01069 
01070    QCString aValue = readEntryUtf8(pKey);
01071 
01072   if (!aValue.isEmpty())
01073   {
01074     int left, top, width, height;
01075 
01076     if (sscanf(aValue.data(), "%d,%d,%d,%d", &left, &top, &width, &height) == 4)
01077     {
01078        return QRect(left, top, width, height);
01079     }
01080   }
01081   if (pDefault)
01082     return *pDefault;
01083   return QRect();
01084 }
01085 
01086 
01087 QPoint KConfigBase::readPointEntry( const QString& pKey,
01088                                     const QPoint* pDefault ) const
01089 {
01090   return readPointEntry(pKey.utf8().data(), pDefault);
01091 }
01092 
01093 QPoint KConfigBase::readPointEntry( const char *pKey,
01094                                     const QPoint* pDefault ) const
01095 {
01096    if ( pDefault )
01097       dumpConfig( pKey, QString::number( pDefault->x() ) + "," + QString::number( pDefault->y() ), "Point" );
01098    else
01099       dumpConfig( pKey, "", "Point" );
01100   
01101   QCString aValue = readEntryUtf8(pKey);
01102 
01103   if (!aValue.isEmpty())
01104   {
01105     int x,y;
01106 
01107     if (sscanf(aValue.data(), "%d,%d", &x, &y) == 2)
01108     {
01109        return QPoint(x,y);
01110     }
01111   }
01112   if (pDefault)
01113     return *pDefault;
01114   return QPoint();
01115 }
01116 
01117 QSize KConfigBase::readSizeEntry( const QString& pKey,
01118                                   const QSize* pDefault ) const
01119 {
01120   return readSizeEntry(pKey.utf8().data(), pDefault);
01121 }
01122 
01123 QSize KConfigBase::readSizeEntry( const char *pKey,
01124                                   const QSize* pDefault ) const
01125 {
01126    if ( pDefault )
01127       dumpConfig( pKey, QString::number( pDefault->width() ) + "x" + QString::number( pDefault->height() ), "Size" );
01128    else
01129       dumpConfig( pKey, "", "Size" );
01130   QCString aValue = readEntryUtf8(pKey);
01131 
01132   if (!aValue.isEmpty())
01133   {
01134     int width,height;
01135 
01136     if (sscanf(aValue.data(), "%d,%d", &width, &height) == 2)
01137     {
01138        return QSize(width, height);
01139     }
01140   }
01141   if (pDefault)
01142     return *pDefault;
01143   return QSize();
01144 }
01145 
01146 
01147 QColor KConfigBase::readColorEntry( const QString& pKey,
01148                                     const QColor* pDefault ) const
01149 { 
01150    return readColorEntry(pKey.utf8().data(), pDefault);
01151 }
01152 
01153 QColor KConfigBase::readColorEntry( const char *pKey,
01154                                     const QColor* pDefault ) const
01155 {
01156    if ( pDefault )
01157       dumpConfig( pKey, pDefault->name(), "Color" );
01158    else
01159       dumpConfig( pKey, "", "Color" );
01160   QColor aRetColor;
01161   int nRed = 0, nGreen = 0, nBlue = 0;
01162 
01163   QString aValue = readEntry( pKey );
01164   if( !aValue.isEmpty() )
01165     {
01166       if ( aValue.at(0) == '#' )
01167         {
01168           aRetColor.setNamedColor(aValue);
01169         }
01170       else
01171         {
01172 
01173           bool bOK;
01174 
01175           // find first part (red)
01176           int nIndex = aValue.find( ',' );
01177 
01178           if( nIndex == -1 ){
01179             // return a sensible default -- Bernd
01180             if( pDefault )
01181               aRetColor = *pDefault;
01182             return aRetColor;
01183           }
01184 
01185           nRed = aValue.left( nIndex ).toInt( &bOK );
01186 
01187           // find second part (green)
01188           int nOldIndex = nIndex;
01189           nIndex = aValue.find( ',', nOldIndex+1 );
01190 
01191           if( nIndex == -1 ){
01192             // return a sensible default -- Bernd
01193             if( pDefault )
01194               aRetColor = *pDefault;
01195             return aRetColor;
01196           }
01197           nGreen = aValue.mid( nOldIndex+1,
01198                                nIndex-nOldIndex-1 ).toInt( &bOK );
01199 
01200           // find third part (blue)
01201           nBlue = aValue.right( aValue.length()-nIndex-1 ).toInt( &bOK );
01202 
01203           aRetColor.setRgb( nRed, nGreen, nBlue );
01204         }
01205     }
01206   else {
01207 
01208     if( pDefault )
01209       aRetColor = *pDefault;
01210   }
01211 
01212   return aRetColor;
01213 }
01214 
01215 
01216 QDateTime KConfigBase::readDateTimeEntry( const QString& pKey,
01217                                           const QDateTime* pDefault ) const
01218 {
01219   return readDateTimeEntry(pKey.utf8().data(), pDefault);
01220 }
01221 
01222 // ### currentDateTime() as fallback ? (Harri)
01223 QDateTime KConfigBase::readDateTimeEntry( const char *pKey,
01224                                           const QDateTime* pDefault ) const
01225 {
01226    if ( pDefault )
01227       dumpConfig( pKey, pDefault->toString(), "DateTime" );
01228    else
01229       dumpConfig( pKey, "", "DateTime" );
01230 
01231   if( !hasKey( pKey ) )
01232     {
01233       if( pDefault )
01234         return *pDefault;
01235       else
01236         return QDateTime::currentDateTime();
01237     }
01238 
01239   QStrList list;
01240   int count = readListEntry( pKey, list, ',' );
01241   if( count == 6 ) {
01242     QDate date( atoi( list.at( 0 ) ), atoi( list.at( 1 ) ),
01243                 atoi( list.at( 2 ) ) );
01244     QTime time( atoi( list.at( 3 ) ), atoi( list.at( 4 ) ),
01245                 atoi( list.at( 5 ) ) );
01246 
01247     return QDateTime( date, time );
01248   }
01249 
01250   return QDateTime::currentDateTime();
01251 }
01252 
01253 void KConfigBase::writeEntry( const QString& pKey, const QString& value,
01254                                  bool bPersistent,
01255                                  bool bGlobal,
01256                                  bool bNLS )
01257 {
01258    writeEntry(pKey.utf8().data(), value, bPersistent,  bGlobal, bNLS);
01259 }
01260 
01261 void KConfigBase::writeEntry( const char *pKey, const QString& value,
01262                                  bool bPersistent,
01263                                  bool bGlobal,
01264                                  bool bNLS )
01265 {
01266   // the KConfig object is dirty now
01267   // set this before any IO takes place so that if any derivative
01268   // classes do caching, they won't try and flush the cache out
01269   // from under us before we read. A race condition is still
01270   // possible but minimized.
01271   if( bPersistent )
01272     setDirty(true);
01273 
01274   if (!bLocaleInitialized && KGlobal::locale())
01275     setLocale();
01276 
01277   KEntryKey entryKey(mGroup, pKey);
01278   entryKey.bLocal = bNLS;
01279 
01280   KEntry aEntryData;
01281   aEntryData.mValue = value.utf8();  // set new value
01282   aEntryData.bGlobal = bGlobal;
01283   aEntryData.bNLS = bNLS;
01284 
01285   if (bPersistent)
01286     aEntryData.bDirty = true;
01287 
01288   // rewrite the new value
01289   putData(entryKey, aEntryData, true);
01290 }
01291 
01292 void KConfigBase::writePathEntry( const QString& pKey, const QString & path,
01293                                   bool bPersistent, bool bGlobal,
01294                                   bool bNLS)
01295 {
01296    writePathEntry(pKey.utf8().data(), path, bPersistent, bGlobal, bNLS);
01297 }
01298 
01299 
01300 static bool cleanHomeDirPath( QString &path, const QString &homeDir )
01301 {
01302 #ifdef Q_WS_WIN //safer
01303    if (!QDir::convertSeparators(path).startsWith(QDir::convertSeparators(homeDir)))
01304         return false;
01305 #else
01306    if (!path.startsWith(homeDir))
01307         return false;
01308 #endif
01309 
01310    unsigned int len = homeDir.length();
01311    // replace by "$HOME" if possible
01312    if (len && (path.length() == len || path[len] == '/')) {
01313         path.replace(0, len, QString::fromLatin1("$HOME"));
01314         return true;
01315    } else
01316         return false;
01317 }
01318 
01319 static QString translatePath( QString path )
01320 {
01321    if (path.isEmpty())
01322        return path;
01323 
01324    // only "our" $HOME should be interpreted
01325    path.replace('$', "$$");
01326 
01327    bool startsWithFile = path.startsWith("file:", false);
01328 
01329    // return original path, if it refers to another type of URL (e.g. http:/), or
01330    // if the path is already relative to another directory
01331    if (!startsWithFile && path[0] != '/' ||
01332         startsWithFile && path[5] != '/')
01333     return path;
01334 
01335    if (startsWithFile)
01336         path.remove(0,5); // strip leading "file:/" off the string
01337 
01338    // keep only one single '/' at the beginning - needed for cleanHomeDirPath()
01339    while (path[0] == '/' && path[1] == '/')
01340     path.remove(0,1);
01341 
01342    // we can not use KGlobal::dirs()->relativeLocation("home", path) here,
01343    // since it would not recognize paths without a trailing '/'.
01344    // All of the 3 following functions to return the user's home directory
01345    // can return different paths. We have to test all them.
01346    QString homeDir0 = QFile::decodeName(getenv("HOME"));
01347    QString homeDir1 = QDir::homeDirPath();
01348    QString homeDir2 = QDir(homeDir1).canonicalPath();
01349    if (cleanHomeDirPath(path, homeDir0) ||
01350        cleanHomeDirPath(path, homeDir1) ||
01351        cleanHomeDirPath(path, homeDir2) ) {
01352      // kdDebug() << "Path was replaced\n";
01353    }
01354 
01355    if (startsWithFile)
01356       path.prepend( "file://" );
01357 
01358    return path;
01359 }
01360 
01361 void KConfigBase::writePathEntry( const char *pKey, const QString & path,
01362                                   bool bPersistent, bool bGlobal,
01363                                   bool bNLS)
01364 {
01365    writeEntry(pKey, translatePath(path), bPersistent, bGlobal, bNLS);
01366 }
01367 
01368 void KConfigBase::writePathEntry ( const QString& pKey, const QStringList &list,
01369                                char sep , bool bPersistent,
01370                                bool bGlobal, bool bNLS )
01371 {
01372   writePathEntry(pKey.utf8().data(), list, sep, bPersistent, bGlobal, bNLS);
01373 }
01374 
01375 void KConfigBase::writePathEntry ( const char *pKey, const QStringList &list,
01376                                char sep , bool bPersistent,
01377                                bool bGlobal, bool bNLS )
01378 {
01379   if( list.isEmpty() )
01380     {
01381       writeEntry( pKey, QString::fromLatin1(""), bPersistent );
01382       return;
01383     }
01384   QStringList new_list;
01385   QStringList::ConstIterator it = list.begin();
01386   for( ; it != list.end(); ++it )
01387     {
01388       QString value = *it;
01389       new_list.append( translatePath(value) );
01390     }
01391   writeEntry( pKey, new_list, sep, bPersistent, bGlobal, bNLS );
01392 }
01393 
01394 void KConfigBase::deleteEntry( const QString& pKey,
01395                                  bool bNLS,
01396                                  bool bGlobal)
01397 {
01398    deleteEntry(pKey.utf8().data(), bNLS, bGlobal);
01399 }
01400 
01401 void KConfigBase::deleteEntry( const char *pKey,
01402                                  bool bNLS,
01403                                  bool bGlobal)
01404 {
01405   // the KConfig object is dirty now
01406   // set this before any IO takes place so that if any derivative
01407   // classes do caching, they won't try and flush the cache out
01408   // from under us before we read. A race condition is still
01409   // possible but minimized.
01410   setDirty(true);
01411 
01412   if (!bLocaleInitialized && KGlobal::locale())
01413     setLocale();
01414 
01415   KEntryKey entryKey(mGroup, pKey);
01416   KEntry aEntryData;
01417 
01418   aEntryData.bGlobal = bGlobal;
01419   aEntryData.bNLS = bNLS;
01420   aEntryData.bDirty = true;
01421   aEntryData.bDeleted = true;
01422 
01423   // rewrite the new value
01424   putData(entryKey, aEntryData, true);
01425 }
01426 
01427 bool KConfigBase::deleteGroup( const QString& group, bool bDeep, bool bGlobal )
01428 {
01429   KEntryMap aEntryMap = internalEntryMap(group);
01430 
01431   if (!bDeep) {
01432     // Check if it empty
01433     return aEntryMap.isEmpty();
01434   }
01435 
01436   bool dirty = false;
01437   bool checkGroup = true;
01438   // we want to remove all entries in the group
01439   KEntryMapIterator aIt;
01440   for (aIt = aEntryMap.begin(); aIt != aEntryMap.end(); ++aIt)
01441   {
01442     if (!aIt.key().mKey.isEmpty() && !aIt.key().bDefault && !(*aIt).bDeleted)
01443     {
01444       (*aIt).bDeleted = true;
01445       (*aIt).bDirty = true;
01446       (*aIt).bGlobal = bGlobal;
01447       (*aIt).mValue = 0;
01448       putData(aIt.key(), *aIt, checkGroup);
01449       checkGroup = false;
01450       dirty = true;
01451     }
01452   }
01453   if (dirty)
01454      setDirty(true);
01455   return true;
01456 }
01457 
01458 void KConfigBase::writeEntry ( const QString& pKey, const QVariant &prop,
01459                                bool bPersistent,
01460                                bool bGlobal, bool bNLS )
01461 {
01462   writeEntry(pKey.utf8().data(), prop, bPersistent, bGlobal, bNLS);
01463 }
01464 
01465 void KConfigBase::writeEntry ( const char *pKey, const QVariant &prop,
01466                                bool bPersistent,
01467                                bool bGlobal, bool bNLS )
01468 {
01469   switch( prop.type() )
01470     {
01471     case QVariant::Invalid:
01472       writeEntry( pKey, "", bPersistent, bGlobal, bNLS );
01473       return;
01474     case QVariant::String:
01475       writeEntry( pKey, prop.toString(), bPersistent, bGlobal, bNLS );
01476       return;
01477     case QVariant::StringList:
01478       writeEntry( pKey, prop.toStringList(), ',', bPersistent, bGlobal, bNLS );
01479       return;
01480     case QVariant::List: {
01481         QValueList<QVariant> list = prop.toList();
01482         QValueList<QVariant>::ConstIterator it = list.begin();
01483         QValueList<QVariant>::ConstIterator end = list.end();
01484         QStringList strList;
01485 
01486         for (; it != end; ++it )
01487             strList.append( (*it).toString() );
01488 
01489         writeEntry( pKey, strList, ',', bPersistent, bGlobal, bNLS );
01490 
01491         return;
01492     }
01493     case QVariant::Font:
01494       writeEntry( pKey, prop.toFont(), bPersistent, bGlobal, bNLS );
01495       return;
01496     case QVariant::Point:
01497       writeEntry( pKey, prop.toPoint(), bPersistent, bGlobal, bNLS );
01498       return;
01499     case QVariant::Rect:
01500       writeEntry( pKey, prop.toRect(), bPersistent, bGlobal, bNLS );
01501       return;
01502     case QVariant::Size:
01503       writeEntry( pKey, prop.toSize(), bPersistent, bGlobal, bNLS );
01504       return;
01505     case QVariant::Color:
01506       writeEntry( pKey, prop.toColor(), bPersistent, bGlobal, bNLS );
01507       return;
01508     case QVariant::Int:
01509       writeEntry( pKey, prop.toInt(), bPersistent, bGlobal, bNLS );
01510       return;
01511     case QVariant::UInt:
01512       writeEntry( pKey, prop.toUInt(), bPersistent, bGlobal, bNLS );
01513       return;
01514     case QVariant::LongLong:
01515       writeEntry( pKey, prop.toLongLong(), bPersistent, bGlobal, bNLS );
01516       return;
01517     case QVariant::ULongLong:
01518       writeEntry( pKey, prop.toULongLong(), bPersistent, bGlobal, bNLS );
01519       return;
01520     case QVariant::Bool:
01521       writeEntry( pKey, prop.toBool(), bPersistent, bGlobal, bNLS );
01522       return;
01523     case QVariant::Double:
01524       writeEntry( pKey, prop.toDouble(), bPersistent, bGlobal, 'g', 6, bNLS );
01525       return;
01526     case QVariant::DateTime:
01527       writeEntry( pKey, prop.toDateTime(), bPersistent, bGlobal, bNLS);
01528       return;
01529     case QVariant::Date:
01530       writeEntry( pKey, QDateTime(prop.toDate()), bPersistent, bGlobal, bNLS);
01531       return;
01532 
01533     case QVariant::Pixmap:
01534     case QVariant::Image:
01535     case QVariant::Brush:
01536     case QVariant::Palette:
01537     case QVariant::ColorGroup:
01538     case QVariant::Map:
01539     case QVariant::IconSet:
01540     case QVariant::CString:
01541     case QVariant::PointArray:
01542     case QVariant::Region:
01543     case QVariant::Bitmap:
01544     case QVariant::Cursor:
01545     case QVariant::SizePolicy:
01546     case QVariant::Time:
01547     case QVariant::ByteArray:
01548     case QVariant::BitArray:
01549     case QVariant::KeySequence:
01550     case QVariant::Pen:
01551         break;
01552     }
01553 
01554   Q_ASSERT( 0 );
01555 }
01556 
01557 void KConfigBase::writeEntry ( const QString& pKey, const QStrList &list,
01558                                char sep , bool bPersistent,
01559                                bool bGlobal, bool bNLS )
01560 {
01561   writeEntry(pKey.utf8().data(), list, sep, bPersistent, bGlobal, bNLS);
01562 }
01563 
01564 void KConfigBase::writeEntry ( const char *pKey, const QStrList &list,
01565                                char sep , bool bPersistent,
01566                                bool bGlobal, bool bNLS )
01567 {
01568   if( list.isEmpty() )
01569     {
01570       writeEntry( pKey, QString::fromLatin1(""), bPersistent );
01571       return;
01572     }
01573   QString str_list;
01574   QStrListIterator it( list );
01575   for( ; it.current(); ++it )
01576     {
01577       uint i;
01578       QString value;
01579       // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!!
01580       // A QStrList may contain values in 8bit locale cpecified
01581       // encoding or in UTF8 encoding.
01582       value = KStringHandler::from8Bit(it.current());
01583       uint strLengh(value.length());
01584       for( i = 0; i < strLengh; i++ )
01585         {
01586           if( value[i] == sep || value[i] == '\\' )
01587             str_list += '\\';
01588           str_list += value[i];
01589         }
01590       str_list += sep;
01591     }
01592   if( str_list.at(str_list.length() - 1) == sep )
01593     str_list.truncate( str_list.length() -1 );
01594   writeEntry( pKey, str_list, bPersistent, bGlobal, bNLS );
01595 }
01596 
01597 void KConfigBase::writeEntry ( const QString& pKey, const QStringList &list,
01598                                char sep , bool bPersistent,
01599                                bool bGlobal, bool bNLS )
01600 {
01601   writeEntry(pKey.utf8().data(), list, sep, bPersistent, bGlobal, bNLS);
01602 }
01603 
01604 void KConfigBase::writeEntry ( const char *pKey, const QStringList &list,
01605                                char sep , bool bPersistent,
01606                                bool bGlobal, bool bNLS )
01607 {
01608   if( list.isEmpty() )
01609     {
01610       writeEntry( pKey, QString::fromLatin1(""), bPersistent );
01611       return;
01612     }
01613   QString str_list;
01614   str_list.reserve( 4096 );
01615   QStringList::ConstIterator it = list.begin();
01616   for( ; it != list.end(); ++it )
01617     {
01618       QString value = *it;
01619       uint i;
01620       uint strLength(value.length());
01621       for( i = 0; i < strLength; i++ )
01622         {
01623           if( value[i] == sep || value[i] == '\\' )
01624             str_list += '\\';
01625           str_list += value[i];
01626         }
01627       str_list += sep;
01628     }
01629   if( str_list.at(str_list.length() - 1) == sep )
01630     str_list.truncate( str_list.length() -1 );
01631   writeEntry( pKey, str_list, bPersistent, bGlobal, bNLS );
01632 }
01633 
01634 void KConfigBase::writeEntry ( const QString& pKey, const QValueList<int> &list,
01635                                bool bPersistent, bool bGlobal, bool bNLS )
01636 {
01637   writeEntry(pKey.utf8().data(), list, bPersistent, bGlobal, bNLS);
01638 }
01639 
01640 void KConfigBase::writeEntry ( const char *pKey, const QValueList<int> &list,
01641                                bool bPersistent, bool bGlobal, bool bNLS )
01642 {
01643     QStringList strlist;
01644     QValueList<int>::ConstIterator end = list.end();
01645     for (QValueList<int>::ConstIterator it = list.begin(); it != end; it++)
01646         strlist << QString::number(*it);
01647     writeEntry(pKey, strlist, ',', bPersistent, bGlobal, bNLS );
01648 }
01649 
01650 void KConfigBase::writeEntry( const QString& pKey, int nValue,
01651                                  bool bPersistent, bool bGlobal,
01652                                  bool bNLS )
01653 {
01654   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01655 }
01656 
01657 void KConfigBase::writeEntry( const char *pKey, int nValue,
01658                                  bool bPersistent, bool bGlobal,
01659                                  bool bNLS )
01660 {
01661   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01662 }
01663 
01664 
01665 void KConfigBase::writeEntry( const QString& pKey, unsigned int nValue,
01666                                  bool bPersistent, bool bGlobal,
01667                                  bool bNLS )
01668 {
01669   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01670 }
01671 
01672 void KConfigBase::writeEntry( const char *pKey, unsigned int nValue,
01673                                  bool bPersistent, bool bGlobal,
01674                                  bool bNLS )
01675 {
01676   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01677 }
01678 
01679 
01680 void KConfigBase::writeEntry( const QString& pKey, long nValue,
01681                                  bool bPersistent, bool bGlobal,
01682                                  bool bNLS )
01683 {
01684   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01685 }
01686 
01687 void KConfigBase::writeEntry( const char *pKey, long nValue,
01688                                  bool bPersistent, bool bGlobal,
01689                                  bool bNLS )
01690 {
01691   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01692 }
01693 
01694 
01695 void KConfigBase::writeEntry( const QString& pKey, unsigned long nValue,
01696                                  bool bPersistent, bool bGlobal,
01697                                  bool bNLS )
01698 {
01699   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01700 }
01701 
01702 void KConfigBase::writeEntry( const char *pKey, unsigned long nValue,
01703                                  bool bPersistent, bool bGlobal,
01704                                  bool bNLS )
01705 {
01706   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01707 }
01708 
01709 void KConfigBase::writeEntry( const QString& pKey, Q_INT64 nValue,
01710                                  bool bPersistent, bool bGlobal,
01711                                  bool bNLS )
01712 {
01713   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01714 }
01715 
01716 void KConfigBase::writeEntry( const char *pKey, Q_INT64 nValue,
01717                                  bool bPersistent, bool bGlobal,
01718                                  bool bNLS )
01719 {
01720   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01721 }
01722 
01723 
01724 void KConfigBase::writeEntry( const QString& pKey, Q_UINT64 nValue,
01725                                  bool bPersistent, bool bGlobal,
01726                                  bool bNLS )
01727 {
01728   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01729 }
01730 
01731 void KConfigBase::writeEntry( const char *pKey, Q_UINT64 nValue,
01732                                  bool bPersistent, bool bGlobal,
01733                                  bool bNLS )
01734 {
01735   writeEntry( pKey, QString::number(nValue), bPersistent, bGlobal, bNLS );
01736 }
01737 
01738 void KConfigBase::writeEntry( const QString& pKey, double nValue,
01739                                  bool bPersistent, bool bGlobal,
01740                                  char format, int precision,
01741                                  bool bNLS )
01742 {
01743   writeEntry( pKey, QString::number(nValue, format, precision),
01744                      bPersistent, bGlobal, bNLS );
01745 }
01746 
01747 void KConfigBase::writeEntry( const char *pKey, double nValue,
01748                                  bool bPersistent, bool bGlobal,
01749                                  char format, int precision,
01750                                  bool bNLS )
01751 {
01752   writeEntry( pKey, QString::number(nValue, format, precision),
01753                      bPersistent, bGlobal, bNLS );
01754 }
01755 
01756 
01757 void KConfigBase::writeEntry( const QString& pKey, bool bValue,
01758                                  bool bPersistent,
01759                                  bool bGlobal,
01760                                  bool bNLS )
01761 {
01762   writeEntry(pKey.utf8().data(), bValue, bPersistent, bGlobal, bNLS);
01763 }
01764 
01765 void KConfigBase::writeEntry( const char *pKey, bool bValue,
01766                                  bool bPersistent,
01767                                  bool bGlobal,
01768                                  bool bNLS )
01769 {
01770   QString aValue;
01771 
01772   if( bValue )
01773     aValue = "true";
01774   else
01775     aValue = "false";
01776 
01777   writeEntry( pKey, aValue, bPersistent, bGlobal, bNLS );
01778 }
01779 
01780 
01781 void KConfigBase::writeEntry( const QString& pKey, const QFont& rFont,
01782                                  bool bPersistent, bool bGlobal,
01783                                  bool bNLS )
01784 {
01785   writeEntry(pKey.utf8().data(), rFont, bPersistent, bGlobal, bNLS);
01786 }
01787 
01788 void KConfigBase::writeEntry( const char *pKey, const QFont& rFont,
01789                                  bool bPersistent, bool bGlobal,
01790                                  bool bNLS )
01791 {
01792   writeEntry( pKey, rFont.toString(), bPersistent, bGlobal, bNLS );
01793 }
01794 
01795 
01796 void KConfigBase::writeEntry( const QString& pKey, const QRect& rRect,
01797                               bool bPersistent, bool bGlobal,
01798                               bool bNLS )
01799 {
01800   writeEntry(pKey.utf8().data(), rRect, bPersistent, bGlobal, bNLS);
01801 }
01802 
01803 void KConfigBase::writeEntry( const char *pKey, const QRect& rRect,
01804                               bool bPersistent, bool bGlobal,
01805                               bool bNLS )
01806 {
01807   QStrList list;
01808   QCString tempstr;
01809   list.insert( 0, tempstr.setNum( rRect.left() ) );
01810   list.insert( 1, tempstr.setNum( rRect.top() ) );
01811   list.insert( 2, tempstr.setNum( rRect.width() ) );
01812   list.insert( 3, tempstr.setNum( rRect.height() ) );
01813 
01814   writeEntry( pKey, list, ',', bPersistent, bGlobal, bNLS );
01815 }
01816 
01817 
01818 void KConfigBase::writeEntry( const QString& pKey, const QPoint& rPoint,
01819                               bool bPersistent, bool bGlobal,
01820                               bool bNLS )
01821 {
01822   writeEntry(pKey.utf8().data(), rPoint, bPersistent, bGlobal, bNLS);
01823 }
01824 
01825 void KConfigBase::writeEntry( const char *pKey, const QPoint& rPoint,
01826                               bool bPersistent, bool bGlobal,
01827                               bool bNLS )
01828 {
01829   QStrList list;
01830   QCString tempstr;
01831   list.insert( 0, tempstr.setNum( rPoint.x() ) );
01832   list.insert( 1, tempstr.setNum( rPoint.y() ) );
01833 
01834   writeEntry( pKey, list, ',', bPersistent, bGlobal, bNLS );
01835 }
01836 
01837 
01838 void KConfigBase::writeEntry( const QString& pKey, const QSize& rSize,
01839                               bool bPersistent, bool bGlobal,
01840                               bool bNLS )
01841 {
01842   writeEntry(pKey.utf8().data(), rSize, bPersistent, bGlobal, bNLS);
01843 }
01844 
01845 void KConfigBase::writeEntry( const char *pKey, const QSize& rSize,
01846                               bool bPersistent, bool bGlobal,
01847                               bool bNLS )
01848 {
01849   QStrList list;
01850   QCString tempstr;
01851   list.insert( 0, tempstr.setNum( rSize.width() ) );
01852   list.insert( 1, tempstr.setNum( rSize.height() ) );
01853 
01854   writeEntry( pKey, list, ',', bPersistent, bGlobal, bNLS );
01855 }
01856 
01857 void KConfigBase::writeEntry( const QString& pKey, const QColor& rColor,
01858                               bool bPersistent,
01859                               bool bGlobal,
01860                               bool bNLS  )
01861 {
01862   writeEntry( pKey.utf8().data(), rColor, bPersistent, bGlobal, bNLS);
01863 }
01864 
01865 void KConfigBase::writeEntry( const char *pKey, const QColor& rColor,
01866                               bool bPersistent,
01867                               bool bGlobal,
01868                               bool bNLS  )
01869 {
01870   QString aValue;
01871   if (rColor.isValid())
01872       aValue.sprintf( "%d,%d,%d", rColor.red(), rColor.green(), rColor.blue() );
01873   else
01874       aValue = "invalid";
01875 
01876   writeEntry( pKey, aValue, bPersistent, bGlobal, bNLS );
01877 }
01878 
01879 void KConfigBase::writeEntry( const QString& pKey, const QDateTime& rDateTime,
01880                               bool bPersistent, bool bGlobal,
01881                               bool bNLS )
01882 {
01883   writeEntry(pKey.utf8().data(), rDateTime, bPersistent, bGlobal, bNLS);
01884 }
01885 
01886 void KConfigBase::writeEntry( const char *pKey, const QDateTime& rDateTime,
01887                               bool bPersistent, bool bGlobal,
01888                               bool bNLS )
01889 {
01890   QStrList list;
01891   QCString tempstr;
01892 
01893   QTime time = rDateTime.time();
01894   QDate date = rDateTime.date();
01895 
01896   list.insert( 0, tempstr.setNum( date.year() ) );
01897   list.insert( 1, tempstr.setNum( date.month() ) );
01898   list.insert( 2, tempstr.setNum( date.day() ) );
01899 
01900   list.insert( 3, tempstr.setNum( time.hour() ) );
01901   list.insert( 4, tempstr.setNum( time.minute() ) );
01902   list.insert( 5, tempstr.setNum( time.second() ) );
01903 
01904   writeEntry( pKey, list, ',', bPersistent, bGlobal, bNLS );
01905 }
01906 
01907 void KConfigBase::parseConfigFiles()
01908 {
01909 
01910   if (!bLocaleInitialized && KGlobal::_locale) {
01911     setLocale();
01912   }
01913 
01914   for ( KConfigBackEnd* backend = m_Private->backEnds.first();
01915         backend;
01916         backend = m_Private->backEnds.next() )
01917   {
01918       backend->parseConfigFiles();
01919   }
01920 
01921   if (backEnd)
01922   {
01923       bReadOnly = (backEnd->getConfigState() == ReadOnly);
01924   }
01925 
01926 }
01927 
01928 void KConfigBase::sync()
01929 {
01930   if (isReadOnly())
01931     return;
01932 
01933   if (backEnd)
01934      backEnd->sync();
01935   if (bDirty)
01936     rollback();
01937 }
01938 
01939 KConfigBase::ConfigState KConfigBase::getConfigState() const {
01940     if (backEnd)
01941        return backEnd->getConfigState();
01942     return ReadOnly;
01943 }
01944 
01945 void KConfigBase::rollback( bool /*bDeep = true*/ )
01946 {
01947   bDirty = false;
01948 }
01949 
01950 
01951 void KConfigBase::setReadDefaults(bool b)
01952 {
01953   m_Private->readDefaults = b;
01954 }
01955 
01956 bool KConfigBase::readDefaults() const
01957 {
01958   return (m_Private && m_Private->readDefaults);
01959 }
01960 
01961 void KConfigBase::revertToDefault(const QString &key)
01962 {
01963   setDirty(true);
01964 
01965   KEntryKey aEntryKey(mGroup, key.utf8());
01966   aEntryKey.bDefault = true;
01967 
01968   if (!locale().isNull()) {
01969     // try the localized key first
01970     aEntryKey.bLocal = true;
01971     KEntry entry = lookupData(aEntryKey);
01972     if (entry.mValue.isNull())
01973         entry.bDeleted = true;
01974 
01975     entry.bDirty = true;
01976     putData(aEntryKey, entry, true); // Revert
01977     aEntryKey.bLocal = false;
01978   }
01979 
01980   // try the non-localized version
01981   KEntry entry = lookupData(aEntryKey);
01982   if (entry.mValue.isNull())
01983      entry.bDeleted = true;
01984   entry.bDirty = true;
01985   putData(aEntryKey, entry, true); // Revert
01986 }
01987 
01988 bool KConfigBase::hasDefault(const QString &key) const
01989 {
01990   KEntryKey aEntryKey(mGroup, key.utf8());
01991   aEntryKey.bDefault = true;
01992 
01993   if (!locale().isNull()) {
01994     // try the localized key first
01995     aEntryKey.bLocal = true;
01996     KEntry entry = lookupData(aEntryKey);
01997     if (!entry.mValue.isNull())
01998         return true;
01999 
02000     aEntryKey.bLocal = false;
02001   }
02002 
02003   // try the non-localized version
02004   KEntry entry = lookupData(aEntryKey);
02005   if (!entry.mValue.isNull())
02006      return true;
02007 
02008   return false;
02009 }
02010 
02011 
02012 
02013 KConfigGroup::KConfigGroup(KConfigBase *master, const QString &group)
02014 {
02015   mMaster = master;
02016   backEnd = mMaster->backEnd; // Needed for getConfigState()
02017   bLocaleInitialized = true;
02018   bReadOnly = mMaster->bReadOnly;
02019   bExpand = false;
02020   bDirty = false; // Not used
02021   mGroup = group.utf8();
02022   aLocaleString = mMaster->aLocaleString;
02023   setReadDefaults(mMaster->readDefaults());
02024 }
02025 
02026 KConfigGroup::KConfigGroup(KConfigBase *master, const QCString &group)
02027 {
02028   mMaster = master;
02029   backEnd = mMaster->backEnd; // Needed for getConfigState()
02030   bLocaleInitialized = true;
02031   bReadOnly = mMaster->bReadOnly;
02032   bExpand = false;
02033   bDirty = false; // Not used
02034   mGroup = group;
02035   aLocaleString = mMaster->aLocaleString;
02036   setReadDefaults(mMaster->readDefaults());
02037 }
02038 
02039 KConfigGroup::KConfigGroup(KConfigBase *master, const char * group)
02040 {
02041   mMaster = master;
02042   backEnd = mMaster->backEnd; // Needed for getConfigState()
02043   bLocaleInitialized = true;
02044   bReadOnly = mMaster->bReadOnly;
02045   bExpand = false;
02046   bDirty = false; // Not used
02047   mGroup = group;
02048   aLocaleString = mMaster->aLocaleString;
02049   setReadDefaults(mMaster->readDefaults());
02050 }
02051 
02052 void KConfigGroup::deleteGroup(bool bGlobal)
02053 {
02054   mMaster->deleteGroup(KConfigBase::group(), true, bGlobal);
02055 }
02056 
02057 bool KConfigGroup::groupIsImmutable() const
02058 {
02059     return mMaster->groupIsImmutable(KConfigBase::group());
02060 }
02061 
02062 void KConfigGroup::setDirty(bool _bDirty)
02063 {
02064   mMaster->setDirty(_bDirty);
02065 }
02066 
02067 void KConfigGroup::putData(const KEntryKey &_key, const KEntry &_data, bool _checkGroup)
02068 {
02069   mMaster->putData(_key, _data, _checkGroup);
02070 }
02071 
02072 KEntry KConfigGroup::lookupData(const KEntryKey &_key) const
02073 {
02074   return mMaster->lookupData(_key);
02075 }
02076 
02077 void KConfigGroup::sync()
02078 {
02079   mMaster->sync();
02080 }
02081 
02082 void KConfigBase::virtual_hook( int, void* )
02083 { /*BASE::virtual_hook( id, data );*/ }
02084 
02085 void KConfigGroup::virtual_hook( int id, void* data )
02086 { KConfigBase::virtual_hook( id, data ); }
02087 
02088 bool KConfigBase::checkConfigFilesWritable(bool warnUser)
02089 {
02090   if (backEnd)
02091     return backEnd->checkConfigFilesWritable(warnUser);
02092   else
02093     return false;
02094 }
02095 
02096 #include "kconfigbase.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys