00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "qplatformdefs.h"
00039
00040
00041 static inline int qt_open( const char *pathname, int flags, mode_t mode )
00042 { return ::open( pathname, flags, mode ); }
00043 #if defined(open)
00044 # undef open
00045 #endif
00046
00047
00048 #if defined(truncate)
00049 # undef truncate
00050 #endif
00051
00052 #include "qsettings.h"
00053
00054 #ifndef QT_NO_SETTINGS
00055
00056 #include "qdir.h"
00057 #include "qfile.h"
00058 #include "qfileinfo.h"
00059 #include "qmap.h"
00060 #include "qtextstream.h"
00061 #include "qregexp.h"
00062 #include <private/qsettings_p.h>
00063 #ifndef NO_ERRNO_H
00064 #include <errno.h>
00065 #endif
00066
00252 #if defined(Q_OS_UNIX)
00253 typedef int HANDLE;
00254 #define Q_LOCKREAD F_RDLCK
00255 #define Q_LOCKWRITE F_WRLCK
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 static HANDLE openlock( const QString &name, int type )
00268 {
00269 QFileInfo info( name );
00270
00271 QString lockfile = info.dirPath() + "/." + info.fileName() + ".lock";
00272
00273
00274 HANDLE fd = qt_open( QFile::encodeName( lockfile ),
00275 O_RDWR | O_CREAT, S_IRUSR | S_IWUSR );
00276
00277 if ( fd < 0 ) {
00278
00279 return fd;
00280 }
00281
00282 struct flock fl;
00283 fl.l_type = type;
00284 fl.l_whence = SEEK_SET;
00285 fl.l_start = 0;
00286 fl.l_len = 0;
00287 if ( fcntl( fd, F_SETLKW, &fl ) == -1 ) {
00288
00289
00290
00291 close( fd );
00292 fd = -1;
00293 }
00294
00295 return fd;
00296 }
00297
00298
00299
00300
00301
00302 static void closelock( HANDLE fd )
00303 {
00304 if ( fd < 0 ) {
00305
00306 return;
00307 }
00308
00309 struct flock fl;
00310 fl.l_type = F_UNLCK;
00311 fl.l_whence = SEEK_SET;
00312 fl.l_start = 0;
00313 fl.l_len = 0;
00314
00315 (void) fcntl( fd, F_SETLKW, &fl );
00316
00317 close( fd );
00318 }
00319 #endif
00320
00321
00322 QSettingsGroup::QSettingsGroup()
00323 : modified(FALSE)
00324 {
00325 }
00326
00327
00328
00329
00330 void QSettingsHeading::read(const QString &filename)
00331 {
00332 if (! QFileInfo(filename).exists())
00333 return;
00334
00335 #ifndef Q_WS_WIN
00336 HANDLE lockfd = openlock( filename, Q_LOCKREAD );
00337 #endif
00338
00339 QFile file(filename);
00340 if (! file.open(IO_ReadOnly)) {
00341 #if defined(QT_CHECK_STATE)
00342 qWarning("QSettings: failed to open file '%s'", filename.latin1());
00343 #endif
00344 return;
00345 }
00346
00347 git = end();
00348
00349 QTextStream stream(&file);
00350 stream.setEncoding(QTextStream::UnicodeUTF8);
00351 while (! stream.atEnd())
00352 parseLine(stream);
00353
00354 git = end();
00355
00356 file.close();
00357
00358 #ifndef Q_WS_WIN
00359 closelock( lockfd );
00360 #endif
00361 }
00362
00363
00364 void QSettingsHeading::parseLine(QTextStream &stream)
00365 {
00366 QString line = stream.readLine();
00367 if (line.isEmpty())
00368
00369 return;
00370
00371 if (line[0] == QChar('#'))
00372
00373 return;
00374
00375 if (line[0] == QChar('[')) {
00376 QString gname = line;
00377
00378 gname = gname.remove((uint)0, 1);
00379 if (gname[(int)gname.length() - 1] == QChar(']'))
00380 gname = gname.remove(gname.length() - 1, 1);
00381
00382 git = find(gname);
00383 if (git == end())
00384 git = replace(gname, QSettingsGroup());
00385 } else {
00386 if (git == end()) {
00387 #if defined(QT_CHECK_STATE)
00388 qWarning("QSettings: line '%s' out of group", line.latin1());
00389 #endif
00390 return;
00391 }
00392
00393 int i = line.find('=');
00394 if (i == -1) {
00395 #if defined(QT_CHECK_STATE)
00396 qWarning("QSettings: malformed line '%s' in group '%s'",
00397 line.latin1(), git.key().latin1());
00398 #endif
00399 return;
00400 } else {
00401 QString key, value;
00402 key = line.left(i);
00403 value = "";
00404 bool esc=TRUE;
00405 i++;
00406 while (esc) {
00407 esc = FALSE;
00408 for ( ; i < (int)line.length(); i++ ) {
00409 if ( esc ) {
00410 if ( line[i] == 'n' )
00411 value.append('\n');
00412 else if ( line[i] == '0' )
00413 value = QString::null;
00414 else
00415 value.append(line[i]);
00416 esc = FALSE;
00417 } else if ( line[i] == '\\' )
00418 esc = TRUE;
00419 else
00420 value.append(line[i]);
00421 }
00422 if ( esc ) {
00423
00424
00425 if (stream.atEnd()) {
00426 #if defined(QT_CHECK_STATE)
00427 qWarning("QSettings: reached end of file, expected continued line");
00428 #endif
00429 break;
00430 }
00431 value.append('\n');
00432 line = stream.readLine();
00433 i = 0;
00434 }
00435 }
00436
00437 (*git).insert(key, value);
00438 }
00439 }
00440 }
00441
00442 #ifdef Q_WS_WIN // for homedirpath reading from registry
00443 #include "qt_windows.h"
00444 #include "qlibrary.h"
00445
00446 #ifndef CSIDL_APPDATA
00447 #define CSIDL_APPDATA 0x001a // <user name>\Application Data
00448 #endif
00449 #ifndef CSIDL_COMMON_APPDATA
00450 #define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
00451 #endif
00452
00453 #endif
00454
00455 QSettingsPrivate::QSettingsPrivate( QSettings::Format format )
00456 : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE)
00457 {
00458 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
00459 if ( format != QSettings::Ini )
00460 return;
00461 #else
00462 Q_UNUSED( format );
00463 #endif
00464
00465 QString appSettings(QDir::homeDirPath() + "/.qt/");
00466 QString defPath;
00467 #ifdef Q_WS_WIN
00468 #ifdef Q_OS_TEMP
00469 TCHAR path[MAX_PATH];
00470 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
00471 appSettings = QString::fromUcs2( path );
00472 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
00473 defPath = QString::fromUcs2( path );
00474 #else
00475 QLibrary library( "shell32" );
00476 library.setAutoUnload( FALSE );
00477 QT_WA( {
00478 typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL);
00479 GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve( "SHGetSpecialFolderPathW" );
00480 if ( SHGetSpecialFolderPath ) {
00481 TCHAR path[MAX_PATH];
00482 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
00483 appSettings = QString::fromUcs2( (ushort*)path );
00484 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
00485 defPath = QString::fromUcs2( (ushort*)path );
00486 }
00487 } , {
00488 typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int, BOOL);
00489 GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve( "SHGetSpecialFolderPathA" );
00490 if ( SHGetSpecialFolderPath ) {
00491 char path[MAX_PATH];
00492 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
00493 appSettings = QString::fromLocal8Bit( path );
00494 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
00495 defPath = QString::fromLocal8Bit( path );
00496 }
00497 } );
00498 #endif // Q_OS_TEMP
00499 #else
00500 defPath = qInstallPathSysconf();
00501 #endif
00502 QDir dir(appSettings);
00503 if (! dir.exists()) {
00504 if (! dir.mkdir(dir.path()))
00505 #if defined(QT_CHECK_STATE)
00506 qWarning("QSettings: error creating %s", dir.path().latin1());
00507 #else
00508 ;
00509 #endif
00510 }
00511
00512 if ( !!defPath )
00513 searchPaths.append(defPath);
00514 searchPaths.append(dir.path());
00515 }
00516
00517 QSettingsPrivate::~QSettingsPrivate()
00518 {
00519 }
00520
00521 QSettingsGroup QSettingsPrivate::readGroup()
00522 {
00523 QSettingsHeading hd;
00524 QSettingsGroup grp;
00525
00526 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading);
00527 if (headingsit != headings.end())
00528 hd = *headingsit;
00529
00530 QSettingsHeading::Iterator grpit = hd.find(group);
00531 if (grpit == hd.end()) {
00532 QStringList::Iterator it = searchPaths.begin();
00533 if ( !globalScope )
00534 ++it;
00535 while (it != searchPaths.end()) {
00536 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
00537 QString fn((*it++) + "/" + filebase + "rc");
00538 if (! hd.contains(fn + "cached")) {
00539 hd.read(fn);
00540 hd.insert(fn + "cached", QSettingsGroup());
00541 }
00542 }
00543
00544 headings.replace(heading, hd);
00545
00546 grpit = hd.find(group);
00547 if (grpit != hd.end())
00548 grp = *grpit;
00549 } else if (hd.count() != 0)
00550 grp = *grpit;
00551
00552 return grp;
00553 }
00554
00555
00556 void QSettingsPrivate::removeGroup(const QString &key)
00557 {
00558 QSettingsHeading hd;
00559 QSettingsGroup grp;
00560 bool found = FALSE;
00561
00562 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading);
00563 if (headingsit != headings.end())
00564 hd = *headingsit;
00565
00566 QSettingsHeading::Iterator grpit = hd.find(group);
00567 if (grpit == hd.end()) {
00568 QStringList::Iterator it = searchPaths.begin();
00569 if ( !globalScope )
00570 ++it;
00571 while (it != searchPaths.end()) {
00572 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
00573 QString fn((*it++) + "/" + filebase + "rc");
00574 if (! hd.contains(fn + "cached")) {
00575 hd.read(fn);
00576 hd.insert(fn + "cached", QSettingsGroup());
00577 }
00578 }
00579
00580 headings.replace(heading, hd);
00581
00582 grpit = hd.find(group);
00583 if (grpit != hd.end()) {
00584 found = TRUE;
00585 grp = *grpit;
00586 }
00587 } else if (hd.count() != 0) {
00588 found = TRUE;
00589 grp = *grpit;
00590 }
00591
00592 if (found) {
00593 grp.remove(key);
00594
00595 if (grp.count() > 0)
00596 hd.replace(group, grp);
00597 else
00598 hd.remove(group);
00599
00600 if (hd.count() > 0)
00601 headings.replace(heading, hd);
00602 else
00603 headings.remove(heading);
00604
00605 modified = TRUE;
00606 }
00607 }
00608
00609
00610 void QSettingsPrivate::writeGroup(const QString &key, const QString &value)
00611 {
00612 QSettingsHeading hd;
00613 QSettingsGroup grp;
00614
00615 QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading);
00616 if (headingsit != headings.end())
00617 hd = *headingsit;
00618
00619 QSettingsHeading::Iterator grpit = hd.find(group);
00620 if (grpit == hd.end()) {
00621 QStringList::Iterator it = searchPaths.begin();
00622 if ( !globalScope )
00623 ++it;
00624 while (it != searchPaths.end()) {
00625 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
00626 QString fn((*it++) + "/" + filebase + "rc");
00627 if (! hd.contains(fn + "cached")) {
00628 hd.read(fn);
00629 hd.insert(fn + "cached", QSettingsGroup());
00630 }
00631 }
00632
00633 headings.replace(heading, hd);
00634
00635 grpit = hd.find(group);
00636 if (grpit != hd.end())
00637 grp = *grpit;
00638 } else if (hd.count() != 0)
00639 grp = *grpit;
00640
00641 grp.modified = TRUE;
00642 grp.replace(key, value);
00643 hd.replace(group, grp);
00644 headings.replace(heading, hd);
00645
00646 modified = TRUE;
00647 }
00648
00649
00650 QDateTime QSettingsPrivate::modificationTime()
00651 {
00652 QSettingsHeading hd = headings[heading];
00653 QSettingsGroup grp = hd[group];
00654
00655 QDateTime datetime;
00656
00657 QStringList::Iterator it = searchPaths.begin();
00658 if ( !globalScope )
00659 ++it;
00660 while (it != searchPaths.end()) {
00661 QFileInfo fi((*it++) + "/" + heading + "rc");
00662 if (fi.exists() && fi.lastModified() > datetime)
00663 datetime = fi.lastModified();
00664 }
00665
00666 return datetime;
00667 }
00668
00669 bool qt_verify_key( const QString &key )
00670 {
00671 if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\r\\n]" ) ) )
00672 return FALSE;
00673 return TRUE;
00674 }
00675
00676 static QString groupKey( const QString &group, const QString &key )
00677 {
00678 QString grp_key;
00679 if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) {
00680
00681 if ( key.startsWith( "/" ) )
00682 grp_key = key;
00683 else
00684 grp_key = "/" + key;
00685 } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) {
00686 grp_key = group + key;
00687 } else {
00688 grp_key = group + "/" + key;
00689 }
00690 return grp_key;
00691 }
00692
00781 void QSettings::insertSearchPath( System s, const QString &path)
00782 {
00783 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
00784 if ( d->sysd ) {
00785 d->sysInsertSearchPath( s, path );
00786 return;
00787 }
00788 #endif
00789
00790 #if !defined(Q_WS_WIN)
00791 if ( s == Windows )
00792 return;
00793 #endif
00794 #if !defined(Q_OS_MAC)
00795 if ( s == Mac )
00796 return;
00797 #endif
00798
00799 if ( !qt_verify_key( path ) ) {
00800 #if defined(QT_CHECK_STATE)
00801 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
00802 #endif
00803 return;
00804 }
00805
00806 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
00807 if ( d->sysd && s != Unix ) {
00808 #else
00809 if ( s != Unix ) {
00810 #endif
00811 #if !defined(QWS) && defined(Q_OS_MAC)
00812 if(s != Mac)
00813 #endif
00814 return;
00815 }
00816
00817 QString realPath = path;
00818 #if defined(Q_WS_WIN)
00819 QString defPath = d->globalScope ? d->searchPaths.first() : d->searchPaths.last();
00820 realPath = defPath + path;
00821 #endif
00822
00823 QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last());
00824 if (it != d->searchPaths.end()) {
00825 d->searchPaths.insert(it, realPath);
00826 }
00827 }
00828
00829
00837 void QSettings::removeSearchPath( System s, const QString &path)
00838 {
00839 if ( !qt_verify_key( path ) ) {
00840 #if defined(QT_CHECK_STATE)
00841 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
00842 #endif
00843 return;
00844 }
00845
00846 #ifdef Q_WS_WIN
00847 if ( d->sysd ) {
00848 d->sysRemoveSearchPath( s, path );
00849 return;
00850 }
00851 #endif
00852 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
00853 if ( d->sysd && s != Unix ) {
00854 #else
00855 if ( s != Unix ) {
00856 #endif
00857 #if !defined(QWS) && defined(Q_OS_MAC)
00858 if(s != Mac)
00859 #endif
00860 return;
00861 }
00862
00863 if (path == d->searchPaths.first() || path == d->searchPaths.last())
00864 return;
00865
00866 d->searchPaths.remove(path);
00867 }
00868
00869
00873 QSettings::QSettings()
00874 {
00875 d = new QSettingsPrivate( Native );
00876 Q_CHECK_PTR(d);
00877
00878 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
00879 d->sysd = 0;
00880 d->sysInit();
00881 #endif
00882 }
00883
00890 QSettings::QSettings( Format format )
00891 {
00892 d = new QSettingsPrivate( format );
00893 Q_CHECK_PTR(d);
00894
00895 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
00896 d->sysd = 0;
00897 if ( format == Native )
00898 d->sysInit();
00899 #else
00900 Q_UNUSED(format);
00901 #endif
00902 }
00903
00909 QSettings::~QSettings()
00910 {
00911 sync();
00912
00913 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
00914 if ( d->sysd )
00915 d->sysClear();
00916 #endif
00917
00918 delete d;
00919 }
00920
00921
00926 bool QSettings::sync()
00927 {
00928 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
00929 if ( d->sysd )
00930 return d->sysSync();
00931 #endif
00932 if (! d->modified)
00933
00934 return TRUE;
00935
00936 bool success = TRUE;
00937 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin();
00938
00939 while (it != d->headings.end()) {
00940
00941 QSettingsHeading hd(*it);
00942 QSettingsHeading::Iterator hdit = hd.begin();
00943 QString filename;
00944
00945 QStringList::Iterator pit = d->searchPaths.begin();
00946 if ( !d->globalScope )
00947 ++pit;
00948 while (pit != d->searchPaths.end()) {
00949 QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_");
00950 QFileInfo di(*pit);
00951 if ( !di.exists() ) {
00952 QDir dir;
00953 dir.mkdir( *pit );
00954 }
00955
00956 QFileInfo fi((*pit++) + "/" + filebase + "rc");
00957
00958 if ((fi.exists() && fi.isFile() && fi.isWritable()) ||
00959 (! fi.exists() && di.isDir()
00960 #ifndef Q_WS_WIN
00961 && di.isWritable()
00962 #else
00963 && ((qWinVersion()&Qt::WV_NT_based) > Qt::WV_2000 || di.isWritable())
00964 #endif
00965 )) {
00966 filename = fi.filePath();
00967 break;
00968 }
00969 }
00970
00971 ++it;
00972
00973 if ( filename.isEmpty() ) {
00974
00975 #ifdef QT_CHECK_STATE
00976 qWarning("QSettings::sync: filename is null/empty");
00977 #endif // QT_CHECK_STATE
00978
00979 success = FALSE;
00980 continue;
00981 }
00982
00983 #ifndef Q_WS_WIN
00984 HANDLE lockfd = openlock( filename, Q_LOCKWRITE );
00985 #endif
00986
00987 QFile file( filename + ".tmp" );
00988 if (! file.open(IO_WriteOnly)) {
00989
00990 #ifdef QT_CHECK_STATE
00991 qWarning("QSettings::sync: failed to open '%s' for writing",
00992 file.name().latin1());
00993 #endif // QT_CHECK_STATE
00994
00995 success = FALSE;
00996 continue;
00997 }
00998
00999
01000 QTextStream stream(&file);
01001 stream.setEncoding(QTextStream::UnicodeUTF8);
01002
01003 while (hdit != hd.end()) {
01004 if ((*hdit).count() > 0) {
01005 stream << "[" << hdit.key() << "]" << endl;
01006
01007 QSettingsGroup grp(*hdit);
01008 QSettingsGroup::Iterator grpit = grp.begin();
01009
01010 while (grpit != grp.end()) {
01011 QString v = grpit.data();
01012 if ( v.isNull() ) {
01013 v = "\\0";
01014 } else {
01015 v.replace("\\", "\\\\");
01016 v.replace("\n", "\\n");
01017 }
01018
01019 stream << grpit.key() << "=" << v << endl;
01020 ++grpit;
01021 }
01022
01023 stream << endl;
01024 }
01025
01026 ++hdit;
01027 }
01028
01029 if (file.status() != IO_Ok) {
01030
01031 #ifdef QT_CHECK_STATE
01032 qWarning("QSettings::sync: error at end of write");
01033 #endif // QT_CHECK_STATE
01034
01035 success = FALSE;
01036 }
01037
01038 file.close();
01039
01040 if ( success ) {
01041 QDir dir( QFileInfo( file ).dir( TRUE ) );
01042 if ( dir.exists( filename ) && !dir.remove( filename ) ||
01043 !dir.rename( file.name(), filename, TRUE ) ) {
01044
01045 #ifdef QT_CHECK_STATE
01046 qWarning( "QSettings::sync: error writing file '%s'",
01047 QFile::encodeName( filename ).data() );
01048 #endif // QT_CHECK_STATE
01049
01050 success = FALSE;
01051 }
01052 }
01053
01054
01055 file.remove();
01056
01057 #ifndef Q_WS_WIN
01058 closelock( lockfd );
01059 #endif
01060 }
01061
01062 d->modified = FALSE;
01063
01064 return success;
01065 }
01066
01067
01082 bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok )
01083 {
01084 QString grp_key( groupKey( group(), key ) );
01085 if ( !qt_verify_key( grp_key ) ) {
01086 #if defined(QT_CHECK_STATE)
01087 qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01088 #endif
01089 if ( ok )
01090 *ok = FALSE;
01091
01092 return def;
01093 }
01094
01095 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01096 if ( d->sysd )
01097 return d->sysReadBoolEntry( grp_key, def, ok );
01098 #endif
01099
01100 QString value = readEntry( key, ( def ? "true" : "false" ), ok );
01101
01102 if (value.lower() == "true")
01103 return TRUE;
01104 else if (value.lower() == "false")
01105 return FALSE;
01106 else if (value == "1")
01107 return TRUE;
01108 else if (value == "0")
01109 return FALSE;
01110
01111 if (! value.isEmpty())
01112 qWarning("QSettings::readBoolEntry: '%s' is not 'true' or 'false'",
01113 value.latin1());
01114 if ( ok )
01115 *ok = FALSE;
01116 return def;
01117 }
01118
01119
01134 double QSettings::readDoubleEntry(const QString &key, double def, bool *ok )
01135 {
01136 QString grp_key( groupKey( group(), key ) );
01137 if ( !qt_verify_key( grp_key ) ) {
01138 #if defined(QT_CHECK_STATE)
01139 qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01140 #endif
01141 if ( ok )
01142 *ok = FALSE;
01143
01144 return def;
01145 }
01146
01147 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01148 if ( d->sysd )
01149 return d->sysReadDoubleEntry( grp_key, def, ok );
01150 #endif
01151
01152 QString value = readEntry( key, QString::number(def), ok );
01153 bool conv_ok;
01154 double retval = value.toDouble( &conv_ok );
01155 if ( conv_ok )
01156 return retval;
01157 if ( ! value.isEmpty() )
01158 qWarning( "QSettings::readDoubleEntry: '%s' is not a number",
01159 value.latin1() );
01160 if ( ok )
01161 *ok = FALSE;
01162 return def;
01163 }
01164
01165
01180 int QSettings::readNumEntry(const QString &key, int def, bool *ok )
01181 {
01182 QString grp_key( groupKey( group(), key ) );
01183 if ( !qt_verify_key( grp_key ) ) {
01184 #if defined(QT_CHECK_STATE)
01185 qWarning( "QSettings::readNumEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01186 #endif
01187 if ( ok )
01188 *ok = FALSE;
01189 return def;
01190 }
01191
01192 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01193 if ( d->sysd )
01194 return d->sysReadNumEntry( grp_key, def, ok );
01195 #endif
01196
01197 QString value = readEntry( key, QString::number( def ), ok );
01198 bool conv_ok;
01199 int retval = value.toInt( &conv_ok );
01200 if ( conv_ok )
01201 return retval;
01202 if ( ! value.isEmpty() )
01203 qWarning( "QSettings::readNumEntry: '%s' is not a number",
01204 value.latin1() );
01205 if ( ok )
01206 *ok = FALSE;
01207 return def;
01208 }
01209
01210
01225 QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
01226 {
01227 QString grp_key( groupKey( group(), key ) );
01228 if ( !qt_verify_key( grp_key ) ) {
01229 #if defined(QT_CHECK_STATE)
01230 qWarning( "QSettings::readEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01231 #endif
01232 if ( ok )
01233 *ok = FALSE;
01234
01235 return def;
01236 }
01237
01238 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01239 if ( d->sysd )
01240 return d->sysReadEntry( grp_key, def, ok );
01241 #endif
01242
01243 if ( ok )
01244 *ok = FALSE;
01245
01246 QString realkey;
01247
01248 if (grp_key[0] == '/') {
01249
01250 QStringList list(QStringList::split('/', grp_key));
01251
01252 if (list.count() < 2) {
01253 #ifdef QT_CHECK_STATE
01254 qWarning("QSettings::readEntry: invalid key '%s'", grp_key.latin1());
01255 #endif // QT_CHECK_STATE
01256 if ( ok )
01257 *ok = FALSE;
01258 return def;
01259 }
01260
01261 if (list.count() == 2) {
01262 d->heading = list[0];
01263 d->group = "General";
01264 realkey = list[1];
01265 } else {
01266 d->heading = list[0];
01267 d->group = list[1];
01268
01269
01270 list.remove(list.at(1));
01271
01272 list.remove(list.at(0));
01273
01274 realkey = list.join("/");
01275 }
01276 } else {
01277 realkey = grp_key;
01278 }
01279
01280 QSettingsGroup grp = d->readGroup();
01281 QSettingsGroup::const_iterator it = grp.find( realkey ), end = grp.end();
01282 QString retval = def;
01283 if ( it != end ) {
01284
01285 retval = *it;
01286 if ( ok ) *ok = TRUE;
01287 }
01288 return retval;
01289 }
01290
01291
01292 #if !defined(Q_NO_BOOL_TYPE)
01293
01303 bool QSettings::writeEntry(const QString &key, bool value)
01304 {
01305 QString grp_key( groupKey( group(), key ) );
01306 if ( !qt_verify_key( grp_key ) ) {
01307 #if defined(QT_CHECK_STATE)
01308 qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01309 #endif
01310 return FALSE;
01311 }
01312
01313 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01314 if ( d->sysd )
01315 return d->sysWriteEntry( grp_key, value );
01316 #endif
01317 QString s(value ? "true" : "false");
01318 return writeEntry(key, s);
01319 }
01320 #endif
01321
01322
01334 bool QSettings::writeEntry(const QString &key, double value)
01335 {
01336 QString grp_key( groupKey( group(), key ) );
01337 if ( !qt_verify_key( grp_key ) ) {
01338 #if defined(QT_CHECK_STATE)
01339 qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01340 #endif
01341 return FALSE;
01342 }
01343
01344 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01345 if ( d->sysd )
01346 return d->sysWriteEntry( grp_key, value );
01347 #endif
01348 QString s(QString::number(value));
01349 return writeEntry(key, s);
01350 }
01351
01352
01364 bool QSettings::writeEntry(const QString &key, int value)
01365 {
01366 QString grp_key( groupKey( group(), key ) );
01367 if ( !qt_verify_key( grp_key ) ) {
01368 #if defined(QT_CHECK_STATE)
01369 qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01370 #endif
01371 return FALSE;
01372 }
01373
01374 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01375 if ( d->sysd )
01376 return d->sysWriteEntry( grp_key, value );
01377 #endif
01378 QString s(QString::number(value));
01379 return writeEntry(key, s);
01380 }
01381
01382
01399 bool QSettings::writeEntry(const QString &key, const char *value)
01400 {
01401 return writeEntry(key, QString(value));
01402 }
01403
01404
01417 bool QSettings::writeEntry(const QString &key, const QString &value)
01418 {
01419 QString grp_key( groupKey( group(), key ) );
01420 if ( !qt_verify_key( grp_key ) ) {
01421 #if defined(QT_CHECK_STATE)
01422 qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01423 #endif
01424 return FALSE;
01425 }
01426
01427 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01428 if ( d->sysd )
01429 return d->sysWriteEntry( grp_key, value );
01430 #endif
01431
01432
01433 QString realkey;
01434
01435 if (grp_key[0] == '/') {
01436
01437 QStringList list(QStringList::split('/', grp_key));
01438
01439 if (list.count() < 2) {
01440 #ifdef QT_CHECK_STATE
01441 qWarning("QSettings::writeEntry: invalid key '%s'", grp_key.latin1());
01442 #endif // QT_CHECK_STATE
01443
01444 return FALSE;
01445 }
01446
01447 if (list.count() == 2) {
01448 d->heading = list[0];
01449 d->group = "General";
01450 realkey = list[1];
01451 } else {
01452 d->heading = list[0];
01453 d->group = list[1];
01454
01455
01456 list.remove(list.at(1));
01457
01458 list.remove(list.at(0));
01459
01460 realkey = list.join("/");
01461 }
01462 } else {
01463 realkey = grp_key;
01464 }
01465
01466 d->writeGroup(realkey, value);
01467 return TRUE;
01468 }
01469
01470
01478 bool QSettings::removeEntry(const QString &key)
01479 {
01480 QString grp_key( groupKey( group(), key ) );
01481 if ( !qt_verify_key( grp_key ) ) {
01482 #if defined(QT_CHECK_STATE)
01483 qWarning( "QSettings::removeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01484 #endif
01485 return FALSE;
01486 }
01487
01488 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01489 if ( d->sysd )
01490 return d->sysRemoveEntry( grp_key );
01491 #endif
01492
01493 QString realkey;
01494 if (grp_key[0] == '/') {
01495
01496 QStringList list(QStringList::split('/', grp_key));
01497
01498 if (list.count() < 2) {
01499 #ifdef QT_CHECK_STATE
01500 qWarning("QSettings::removeEntry: invalid key '%s'", grp_key.latin1());
01501 #endif // QT_CHECK_STATE
01502
01503 return FALSE;
01504 }
01505
01506 if (list.count() == 2) {
01507 d->heading = list[0];
01508 d->group = "General";
01509 realkey = list[1];
01510 } else {
01511 d->heading = list[0];
01512 d->group = list[1];
01513
01514
01515 list.remove(list.at(1));
01516
01517 list.remove(list.at(0));
01518
01519 realkey = list.join("/");
01520 }
01521 } else {
01522 realkey = grp_key;
01523 }
01524
01525 d->removeGroup(realkey);
01526 return TRUE;
01527 }
01528
01529
01556 QStringList QSettings::entryList(const QString &key) const
01557 {
01558 QString grp_key( groupKey( group(), key ) );
01559 if ( !qt_verify_key( grp_key ) ) {
01560 #if defined(QT_CHECK_STATE)
01561 qWarning( "QSettings::entryList: Invalid key: %s", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01562 #endif
01563 return QStringList();
01564 }
01565
01566 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01567 if ( d->sysd )
01568 return d->sysEntryList( grp_key );
01569 #endif
01570
01571 QString realkey;
01572 if (grp_key[0] == '/') {
01573
01574 QStringList list(QStringList::split('/', grp_key));
01575
01576 if (list.count() < 1) {
01577 #ifdef QT_CHECK_STATE
01578 qWarning("QSettings::listEntries: invalid key '%s'", grp_key.latin1());
01579 #endif // QT_CHECK_STATE
01580
01581 return QStringList();
01582 }
01583
01584 if (list.count() == 1) {
01585 d->heading = list[0];
01586 d->group = "General";
01587 } else {
01588 d->heading = list[0];
01589 d->group = list[1];
01590
01591
01592 list.remove(list.at(1));
01593
01594 list.remove(list.at(0));
01595
01596 realkey = list.join("/");
01597 }
01598 } else
01599 realkey = grp_key;
01600
01601 QSettingsGroup grp = d->readGroup();
01602 QSettingsGroup::Iterator it = grp.begin();
01603 QStringList ret;
01604 QString itkey;
01605 while (it != grp.end()) {
01606 itkey = it.key();
01607 ++it;
01608
01609 if ( realkey.length() > 0 ) {
01610 if ( itkey.left( realkey.length() ) != realkey )
01611 continue;
01612 else
01613 itkey.remove( 0, realkey.length() + 1 );
01614 }
01615
01616 if ( itkey.find( '/' ) != -1 )
01617 continue;
01618
01619 ret << itkey;
01620 }
01621
01622 return ret;
01623 }
01624
01625
01652 QStringList QSettings::subkeyList(const QString &key) const
01653 {
01654 QString grp_key( groupKey( group(), key ) );
01655 if ( !qt_verify_key( grp_key ) ) {
01656 #if defined(QT_CHECK_STATE)
01657 qWarning( "QSettings::subkeyList: Invalid key: %s", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01658 #endif
01659 return QStringList();
01660 }
01661
01662 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01663 if ( d->sysd )
01664 return d->sysSubkeyList( grp_key );
01665 #endif
01666
01667 QString realkey;
01668 int subkeycount = 2;
01669 if (grp_key[0] == '/') {
01670
01671 QStringList list(QStringList::split('/', grp_key));
01672
01673 if (list.count() < 1) {
01674 #ifdef QT_CHECK_STATE
01675 qWarning("QSettings::subkeyList: invalid key '%s'", grp_key.latin1());
01676 #endif // QT_CHECK_STATE
01677
01678 return QStringList();
01679 }
01680
01681 subkeycount = list.count();
01682
01683 if (list.count() == 1) {
01684 d->heading = list[0];
01685 d->group = "General";
01686 } else {
01687 d->heading = list[0];
01688 d->group = list[1];
01689
01690
01691 list.remove(list.at(1));
01692
01693 list.remove(list.at(0));
01694
01695 realkey = list.join("/");
01696 }
01697
01698 } else
01699 realkey = grp_key;
01700
01701 QStringList ret;
01702 if ( subkeycount == 1 ) {
01703 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin();
01704 while ( it != d->headings.end() ) {
01705 if ( it.key() != "General" && ! ret.contains( it.key() ) )
01706 ret << it.key();
01707 ++it;
01708 }
01709
01710 return ret;
01711 }
01712
01713 QSettingsGroup grp = d->readGroup();
01714 QSettingsGroup::Iterator it = grp.begin();
01715 QString itkey;
01716 while (it != grp.end()) {
01717 itkey = it.key();
01718 ++it;
01719
01720 if ( realkey.length() > 0 ) {
01721 if ( itkey.left( realkey.length() ) != realkey )
01722 continue;
01723 else
01724 itkey.remove( 0, realkey.length() + 1 );
01725 }
01726
01727 int slash = itkey.find( '/' );
01728 if ( slash == -1 )
01729 continue;
01730 itkey.truncate( slash );
01731
01732 if ( ! ret.contains( itkey ) )
01733 ret << itkey;
01734 }
01735
01736 return ret;
01737 }
01738
01739
01745 QDateTime QSettings::lastModificationTime( const QString &key )
01746 {
01747 QString grp_key( groupKey( group(), key ) );
01748 if ( !qt_verify_key( grp_key ) ) {
01749 #if defined(QT_CHECK_STATE)
01750 qWarning( "QSettings::lastModificationTime: Invalid key '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
01751 #endif
01752 return QDateTime();
01753 }
01754
01755 #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
01756 if ( d->sysd )
01757 return QDateTime();
01758 #endif
01759
01760 if (grp_key[0] == '/') {
01761
01762 QStringList list(QStringList::split('/', grp_key));
01763
01764 if (list.count() < 2) {
01765 #ifdef QT_CHECK_STATE
01766 qWarning("QSettings::lastModificationTime: Invalid key '%s'", grp_key.latin1());
01767 #endif // QT_CHECK_STATE
01768
01769 return QDateTime();
01770 }
01771
01772 if (list.count() == 2) {
01773 d->heading = list[0];
01774 d->group = "General";
01775 } else {
01776 d->heading = list[0];
01777 d->group = list[1];
01778 }
01779 }
01780
01781 return d->modificationTime();
01782 }
01783
01784
01810 bool QSettings::writeEntry(const QString &key, const QStringList &value,
01811 const QChar &separator)
01812 {
01813 QString s(value.join(separator));
01814 return writeEntry(key, s);
01815 }
01816
01829 bool QSettings::writeEntry(const QString &key, const QStringList &value)
01830 {
01831 QString s;
01832 for (QStringList::ConstIterator it=value.begin(); it!=value.end(); ++it) {
01833 QString el = *it;
01834 if ( el.isNull() ) {
01835 el = "^0";
01836 } else {
01837 el.replace("^", "^^");
01838 }
01839 s+=el;
01840 s+="^e";
01841 }
01842 return writeEntry(key, s);
01843 }
01844
01845
01878 QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok )
01879 {
01880 QString value = readEntry( key, QString::null, ok );
01881 if ( ok && !*ok )
01882 return QStringList();
01883
01884 return QStringList::split(separator, value);
01885 }
01886
01910 QStringList QSettings::readListEntry(const QString &key, bool *ok )
01911 {
01912 QString value = readEntry( key, QString::null, ok );
01913 if ( ok && !*ok )
01914 return QStringList();
01915 QStringList l;
01916 QString s;
01917 bool esc=FALSE;
01918 for (int i=0; i<(int)value.length(); i++) {
01919 if ( esc ) {
01920 if ( value[i] == 'e' ) {
01921 l.append(s);
01922 s="";
01923 } else if ( value[i] == '0' ) {
01924 s=QString::null;
01925 } else {
01926 s.append(value[i]);
01927 }
01928 esc=FALSE;
01929 } else if ( value[i] == '^' ) {
01930 esc = TRUE;
01931 } else {
01932 s.append(value[i]);
01933 if ( i == (int)value.length()-1 )
01934 l.append(s);
01935 }
01936 }
01937 return l;
01938 }
01939
01940 #ifdef Q_OS_MAC
01941 void qt_setSettingsBasePath(const QString &);
01942 #endif
01943
01961 void QSettings::setPath( const QString &domain, const QString &product, Scope scope )
01962 {
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979 d->globalScope = scope == Global;
01980
01981 QString actualSearchPath;
01982 int lastDot = domain.findRev( '.' );
01983
01984 #if defined(Q_WS_WIN)
01985 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product;
01986 insertSearchPath( Windows, actualSearchPath );
01987 #elif !defined(QWS) && defined(Q_OS_MAC)
01988 if(lastDot != -1) {
01989 QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + ".";
01990 if ( !topLevelDomain.isEmpty() )
01991 qt_setSettingsBasePath( topLevelDomain );
01992 }
01993 actualSearchPath = "/" + domain.left( lastDot ) + "." + product;
01994 insertSearchPath( Mac, actualSearchPath );
01995 #else
01996 if (scope == User)
01997 actualSearchPath = QDir::homeDirPath() + "/.";
01998 else
01999 actualSearchPath = QString(qInstallPathSysconf()) + "/";
02000 actualSearchPath += domain.mid( 0, lastDot ) + "/" + product;
02001 insertSearchPath( Unix, actualSearchPath );
02002 #endif
02003 }
02004
02015 void QSettings::beginGroup( const QString &group )
02016 {
02017 d->groupStack.push( group );
02018 d->groupDirty = TRUE;
02019 }
02020
02032 void QSettings::endGroup()
02033 {
02034 d->groupStack.pop();
02035 d->groupDirty = TRUE;
02036 }
02037
02041 void QSettings::resetGroup()
02042 {
02043 d->groupStack.clear();
02044 d->groupDirty = FALSE;
02045 d->groupPrefix = QString::null;
02046 }
02047
02053 QString QSettings::group() const
02054 {
02055 if ( d->groupDirty ) {
02056 d->groupDirty = FALSE;
02057 d->groupPrefix = QString::null;
02058
02059 QValueStack<QString>::Iterator it = d->groupStack.begin();
02060 while ( it != d->groupStack.end() ) {
02061 QString group = *it;
02062 ++it;
02063 if ( group[0] != '/' )
02064 group.prepend( "/" );
02065 d->groupPrefix += group;
02066 }
02067 }
02068 return d->groupPrefix;
02069 }
02070
02071 #endif