summaryrefslogtreecommitdiff
path: root/qmake/tools/qsettings.cpp
Unidiff
Diffstat (limited to 'qmake/tools/qsettings.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qsettings.cpp387
1 files changed, 246 insertions, 141 deletions
diff --git a/qmake/tools/qsettings.cpp b/qmake/tools/qsettings.cpp
index 5de105c..35fc039 100644
--- a/qmake/tools/qsettings.cpp
+++ b/qmake/tools/qsettings.cpp
@@ -1,12 +1,12 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2** $Id$
3** 3**
4** Implementation of QSettings class 4** Implementation of QSettings class
5** 5**
6** Created: 2000.06.26 6** Created : 000626
7** 7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the tools module of the Qt GUI Toolkit. 10** This file is part of the tools module of the Qt GUI Toolkit.
11** 11**
12** This file may be distributed under the terms of the Q Public License 12** This file may be distributed under the terms of the Q Public License
@@ -60,35 +60,35 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
60#include "qtextstream.h" 60#include "qtextstream.h"
61#include "qregexp.h" 61#include "qregexp.h"
62#include <private/qsettings_p.h> 62#include <private/qsettings_p.h>
63#include <errno.h> 63#include <errno.h>
64 64
65/*! 65/*!
66 \class QSettings 66 \class QSettings
67 \brief The QSettings class provides persistent platform-independent application settings. 67 \brief The QSettings class provides persistent platform-independent application settings.
68 68
69 \ingroup io 69 \ingroup io
70 \ingroup misc 70 \ingroup misc
71 \mainclass 71 \mainclass
72 72
73 On Unix systems, QSettings uses text files to store settings. On Windows 73 On Unix systems, QSettings uses text files to store settings. On Windows
74 systems, QSettings uses the system registry. On Mac OS X, QSettings will 74 systems, QSettings uses the system registry. On Mac OS X, QSettings uses
75 behave as on Unix, and store to text files. 75 the Carbon preferences API.
76 76
77 Each setting comprises an identifying key and the data associated with 77 Each setting comprises an identifying key and the data associated with
78 the key. A key is a unicode string which consists of \e two or more 78 the key. A key is a unicode string which consists of \e two or more
79 subkeys. A subkey is a slash, '/', followed by one or more unicode 79 subkeys. A subkey is a slash, '/', followed by one or more unicode
80 characters (excluding slashes, newlines, carriage returns and equals, 80 characters (excluding slashes, newlines, carriage returns and equals,
81 '=', signs). The associated data, called the entry or value, may be a 81 '=', signs). The associated data, called the entry or value, may be a
82 boolean, an integer, a double, a string or a list of strings. Entry 82 boolean, an integer, a double, a string or a list of strings. Entry
83 strings may contain any unicode characters. 83 strings may contain any unicode characters.
84 84
85 If you want to save and restore the entire desktop's settings, i.e. 85 If you want to save and restore the entire desktop's settings, i.e.
86 which applications are running, use QSettings to save the settings 86 which applications are running, use QSettings to save the settings
87 for each individual application and QSessionManager to save the 87 for each individual application and QSessionManager to save the
88 desktop's session. 88 desktop's session.
89 89
90 Example settings: 90 Example settings:
91 \code 91 \code
92 /MyCompany/MyApplication/background color 92 /MyCompany/MyApplication/background color
93 /MyCompany/MyApplication/foreground color 93 /MyCompany/MyApplication/foreground color
94 /MyCompany/MyApplication/geometry/x 94 /MyCompany/MyApplication/geometry/x
@@ -98,33 +98,48 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
98 /MyCompany/MyApplication/recent files/1 98 /MyCompany/MyApplication/recent files/1
99 /MyCompany/MyApplication/recent files/2 99 /MyCompany/MyApplication/recent files/2
100 /MyCompany/MyApplication/recent files/3 100 /MyCompany/MyApplication/recent files/3
101 \endcode 101 \endcode
102 Each line above is a complete key, made up of subkeys. 102 Each line above is a complete key, made up of subkeys.
103 103
104 A typical usage pattern for application startup: 104 A typical usage pattern for reading application startup:
105 \code 105 \code
106 QSettings settings; 106 QSettings settings;
107 settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); 107 settings.setPath( "MyCompany.com", "MyApplication" );
108 // No search path needed for Unix; see notes further on. 108
109 // Use default values if the keys don't exist 109 QString bgColor = settings.readEntry( "/colors/background", "white" );
110 QString bgColor = settings.readEntry( "/MyApplication/background color", "white" ); 110 int width = settings.readNumEntry( "/geometry/width", 640 );
111 int width = settings.readNumEntry( "/MyApplication/geometry/width", 640 );
112 // ... 111 // ...
113 \endcode 112 \endcode
114 113
115 A typical usage pattern for application exit or 'save preferences': 114 A typical usage pattern for application exit or 'save preferences':
116 \code 115 \code
117 QSettings settings; 116 QSettings settings;
118 settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); 117 settings.setPath( "MyCompany.com", "MyApplication" );
119 // No search path needed for Unix; see notes further on. 118
120 settings.writeEntry( "/MyApplication/background color", bgColor ); 119 settings.writeEntry( "/colors/background", bgColor );
121 settings.writeEntry( "/MyApplication/geometry/width", width ); 120 settings.writeEntry( "/geometry/width", width );
122 // ... 121 // ...
123 \endcode 122 \endcode
124 123
124 QSettings can build a key prefix that is prepended to all keys. To
125 build the key prefix, use beginGroup() and endGroup().
126 \code
127 QSettings settings;
128
129 settings.beginGroup( "/MainWindow" );
130 settings.beginGroup( "/Geometry" );
131 int x = settings.readEntry( "/x" );
132 // ...
133 settings.endGroup();
134 settings.beginGroup( "/Toolbars" );
135 // ...
136 settings.endGroup();
137 settings.endGroup();
138 \endcode
139
125 You can get a list of entry-holding keys by calling entryList(), and 140 You can get a list of entry-holding keys by calling entryList(), and
126 a list of key-holding keys using subkeyList(). 141 a list of key-holding keys using subkeyList().
127 142
128 \code 143 \code
129 QStringList keys = entryList( "/MyApplication" ); 144 QStringList keys = entryList( "/MyApplication" );
130 // keys contains 'background color' and 'foreground color'. 145 // keys contains 'background color' and 'foreground color'.
@@ -136,26 +151,40 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
136 // subkeys contains 'geometry' and 'recent files' 151 // subkeys contains 'geometry' and 'recent files'
137 152
138 QStringList subkeys = subkeyList( "/MyApplication/recent files" ); 153 QStringList subkeys = subkeyList( "/MyApplication/recent files" );
139 // subkeys is empty. 154 // subkeys is empty.
140 \endcode 155 \endcode
141 156
142 If you wish to use a different search path call insertSearchPath()
143 as often as necessary to add your preferred paths. Call
144 removeSearchPath() to remove any unwanted paths.
145
146 Since settings for Windows are stored in the registry there are size 157 Since settings for Windows are stored in the registry there are size
147 limits as follows: 158 limits as follows:
148 \list 159 \list
149 \i A subkey may not exceed 255 characters. 160 \i A subkey may not exceed 255 characters.
150 \i An entry's value may not exceed 16,300 characters. 161 \i An entry's value may not exceed 16,300 characters.
151 \i All the values of a key (for example, all the 'recent files' 162 \i All the values of a key (for example, all the 'recent files'
152 subkeys values), may not exceed 65,535 characters. 163 subkeys values), may not exceed 65,535 characters.
153 \endlist 164 \endlist
154 165
155 These limitations are not enforced on Unix. 166 These limitations are not enforced on Unix or Mac OS X.
167
168 If you wish to use a different search path call insertSearchPath()
169 as often as necessary to add your preferred paths. Call
170 removeSearchPath() to remove any unwanted paths.
171
172 \section1 Notes for Mac OS X Applications
173
174 Internal to the CFPreferences API it is not defined (for Mac OS 9
175 support) where the settings will ultimitely be stored. However, at the
176 time of this writing the settings will be stored (either on a global or
177 user basis, preferring locally) into a plist file in
178 $ROOT/System/Library/Preferences (in XML format). QSettings will create
179 an appropriate plist file (com.<first group name>.plist) out of the
180 full path to a key.
181
182 For further information on CFPreferences see also
183 \link http://developer.apple.com/techpubs/macosx/CoreFoundation/PreferenceServices/preferenceservices_carbon.html
184 Apple's Specifications\endlink
156 185
157 \section1 Notes for Unix Applications 186 \section1 Notes for Unix Applications
158 187
159 There is no universally accepted place for storing application 188 There is no universally accepted place for storing application
160 settings under Unix. In the examples the settings file will be 189 settings under Unix. In the examples the settings file will be
161 searched for in the following directories: 190 searched for in the following directories:
@@ -297,26 +326,26 @@ static HANDLE openlock( const QString &name, int /*type*/ )
297 QT_WA( { 326 QT_WA( {
298 fd = CreateFileW( (TCHAR*)name.ucs2(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 327 fd = CreateFileW( (TCHAR*)name.ucs2(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
299 } , { 328 } , {
300 fd = CreateFileA( name.local8Bit(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 329 fd = CreateFileA( name.local8Bit(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
301 } ); 330 } );
302 331
303 if ( !LockFile( fd, 0, 0, -1, -1 ) ) { 332 if ( !LockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ???
304#ifdef QT_CHECK_STATE 333#ifdef QT_CHECK_STATE
305 qWarning( "QSettings: openlock failed!" ); 334 qWarning( "QSettings: openlock failed!" );
306#endif 335#endif
307 } 336 }
308 return fd; 337 return fd;
309} 338}
310 339
311void closelock( HANDLE fd ) 340static void closelock( HANDLE fd )
312{ 341{
313 if ( !fd ) 342 if ( !fd )
314 return; 343 return;
315 344
316 if ( !UnlockFile( fd, 0, 0, -1, -1 ) ) { 345 if ( !UnlockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ???
317#ifdef QT_CHECK_STATE 346#ifdef QT_CHECK_STATE
318 qWarning( "QSettings: closelock failed!"); 347 qWarning( "QSettings: closelock failed!");
319#endif 348#endif
320 } 349 }
321 CloseHandle( fd ); 350 CloseHandle( fd );
322} 351}
@@ -452,15 +481,17 @@ void QSettingsHeading::parseLine(QTextStream &stream)
452 481
453#endif 482#endif
454 483
455QSettingsPrivate::QSettingsPrivate( QSettings::Format format ) 484QSettingsPrivate::QSettingsPrivate( QSettings::Format format )
456 : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE) 485 : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE)
457{ 486{
458#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 487#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
459 if ( format != QSettings::Ini ) 488 if ( format != QSettings::Ini )
460 return; 489 return;
490#else
491 Q_UNUSED( format );
461#endif 492#endif
462 493
463 QString appSettings(QDir::homeDirPath() + "/.qt/"); 494 QString appSettings(QDir::homeDirPath() + "/.qt/");
464 QString defPath; 495 QString defPath;
465#ifdef Q_WS_WIN 496#ifdef Q_WS_WIN
466#ifdef Q_OS_TEMP 497#ifdef Q_OS_TEMP
@@ -503,12 +534,14 @@ QSettingsPrivate::QSettingsPrivate( QSettings::Format format )
503#endif 534#endif
504 QDir dir(appSettings); 535 QDir dir(appSettings);
505 if (! dir.exists()) { 536 if (! dir.exists()) {
506 if (! dir.mkdir(dir.path())) 537 if (! dir.mkdir(dir.path()))
507#if defined(QT_CHECK_STATE) 538#if defined(QT_CHECK_STATE)
508 qWarning("QSettings: error creating %s", dir.path().latin1()); 539 qWarning("QSettings: error creating %s", dir.path().latin1());
540#else
541 ;
509#endif 542#endif
510 } 543 }
511 544
512 if ( !!defPath ) 545 if ( !!defPath )
513 searchPaths.append(defPath); 546 searchPaths.append(defPath);
514 searchPaths.append(dir.path()); 547 searchPaths.append(dir.path());
@@ -527,12 +560,14 @@ QSettingsGroup QSettingsPrivate::readGroup()
527 if (headingsit != headings.end()) 560 if (headingsit != headings.end())
528 hd = *headingsit; 561 hd = *headingsit;
529 562
530 QSettingsHeading::Iterator grpit = hd.find(group); 563 QSettingsHeading::Iterator grpit = hd.find(group);
531 if (grpit == hd.end()) { 564 if (grpit == hd.end()) {
532 QStringList::Iterator it = searchPaths.begin(); 565 QStringList::Iterator it = searchPaths.begin();
566 if ( !globalScope )
567 ++it;
533 while (it != searchPaths.end()) { 568 while (it != searchPaths.end()) {
534 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); 569 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
535 QString fn((*it++) + "/" + filebase + "rc"); 570 QString fn((*it++) + "/" + filebase + "rc");
536 if (! hd.contains(fn + "cached")) { 571 if (! hd.contains(fn + "cached")) {
537 hd.read(fn); 572 hd.read(fn);
538 hd.insert(fn + "cached", QSettingsGroup()); 573 hd.insert(fn + "cached", QSettingsGroup());
@@ -561,12 +596,14 @@ void QSettingsPrivate::removeGroup(const QString &key)
561 if (headingsit != headings.end()) 596 if (headingsit != headings.end())
562 hd = *headingsit; 597 hd = *headingsit;
563 598
564 QSettingsHeading::Iterator grpit = hd.find(group); 599 QSettingsHeading::Iterator grpit = hd.find(group);
565 if (grpit == hd.end()) { 600 if (grpit == hd.end()) {
566 QStringList::Iterator it = searchPaths.begin(); 601 QStringList::Iterator it = searchPaths.begin();
602 if ( !globalScope )
603 ++it;
567 while (it != searchPaths.end()) { 604 while (it != searchPaths.end()) {
568 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); 605 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
569 QString fn((*it++) + "/" + filebase + "rc"); 606 QString fn((*it++) + "/" + filebase + "rc");
570 if (! hd.contains(fn + "cached")) { 607 if (! hd.contains(fn + "cached")) {
571 hd.read(fn); 608 hd.read(fn);
572 hd.insert(fn + "cached", QSettingsGroup()); 609 hd.insert(fn + "cached", QSettingsGroup());
@@ -612,12 +649,14 @@ void QSettingsPrivate::writeGroup(const QString &key, const QString &value)
612 if (headingsit != headings.end()) 649 if (headingsit != headings.end())
613 hd = *headingsit; 650 hd = *headingsit;
614 651
615 QSettingsHeading::Iterator grpit = hd.find(group); 652 QSettingsHeading::Iterator grpit = hd.find(group);
616 if (grpit == hd.end()) { 653 if (grpit == hd.end()) {
617 QStringList::Iterator it = searchPaths.begin(); 654 QStringList::Iterator it = searchPaths.begin();
655 if ( !globalScope )
656 ++it;
618 while (it != searchPaths.end()) { 657 while (it != searchPaths.end()) {
619 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); 658 QString filebase = heading.lower().replace(QRegExp("\\s+"), "_");
620 QString fn((*it++) + "/" + filebase + "rc"); 659 QString fn((*it++) + "/" + filebase + "rc");
621 if (! hd.contains(fn + "cached")) { 660 if (! hd.contains(fn + "cached")) {
622 hd.read(fn); 661 hd.read(fn);
623 hd.insert(fn + "cached", QSettingsGroup()); 662 hd.insert(fn + "cached", QSettingsGroup());
@@ -646,32 +685,40 @@ QDateTime QSettingsPrivate::modificationTime()
646 QSettingsHeading hd = headings[heading]; 685 QSettingsHeading hd = headings[heading];
647 QSettingsGroup grp = hd[group]; 686 QSettingsGroup grp = hd[group];
648 687
649 QDateTime datetime; 688 QDateTime datetime;
650 689
651 QStringList::Iterator it = searchPaths.begin(); 690 QStringList::Iterator it = searchPaths.begin();
691 if ( !globalScope )
692 ++it;
652 while (it != searchPaths.end()) { 693 while (it != searchPaths.end()) {
653 QFileInfo fi((*it++) + "/" + heading + "rc"); 694 QFileInfo fi((*it++) + "/" + heading + "rc");
654 if (fi.exists() && fi.lastModified() > datetime) 695 if (fi.exists() && fi.lastModified() > datetime)
655 datetime = fi.lastModified(); 696 datetime = fi.lastModified();
656 } 697 }
657 698
658 return datetime; 699 return datetime;
659} 700}
660 701
661static bool verifyKey( const QString &key ) 702bool qt_verify_key( const QString &key )
662{ 703{
663 if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\\\r\\\\n" ) ) ) 704 if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\\\r\\\\n" ) ) )
664 return FALSE; 705 return FALSE;
665 return TRUE; 706 return TRUE;
666} 707}
667 708
668static inline QString groupKey( const QString &group, const QString &key ) 709static inline QString groupKey( const QString &group, const QString &key )
669{ 710{
670 if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) 711 if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) {
712 // group is empty, or it contains a single '/', so we just return the key
713 if ( key.startsWith( "/" ) )
714 return key;
715 return "/" + key;
716 } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) {
671 return group + key; 717 return group + key;
718 }
672 return group + "/" + key; 719 return group + "/" + key;
673} 720}
674 721
675/*! 722/*!
676 Inserts \a path into the settings search path. The semantics of \a 723 Inserts \a path into the settings search path. The semantics of \a
677 path depends on the system \a s. 724 path depends on the system \a s.
@@ -683,13 +730,13 @@ static inline QString groupKey( const QString &group, const QString &key )
683 When \a s is \e Windows, and the execution environment is Windows, the 730 When \a s is \e Windows, and the execution environment is Windows, the
684 search path list will be used as the first subfolder of the "Software" 731 search path list will be used as the first subfolder of the "Software"
685 folder in the registry. 732 folder in the registry.
686 733
687 When reading settings the folders are searched forwards from the 734 When reading settings the folders are searched forwards from the
688 first folder (listed below) to the last, returning the first 735 first folder (listed below) to the last, returning the first
689 settings found, and ignoring any folders for which the user doesn't 736 settings found, and ignoring any folders for which the user doesn't
690 have read permission. 737 have read permission.
691 \list 1 738 \list 1
692 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication 739 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication
693 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication 740 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication
694 \i HKEY_CURRENT_USER/Software/MyApplication 741 \i HKEY_CURRENT_USER/Software/MyApplication
695 \i HKEY_LOCAL_MACHINE/Software/MyApplication 742 \i HKEY_LOCAL_MACHINE/Software/MyApplication
@@ -707,13 +754,13 @@ static inline QString groupKey( const QString &group, const QString &key )
707 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication 754 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication
708 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication 755 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication
709 \i HKEY_LOCAL_MACHINE/Software/MyApplication 756 \i HKEY_LOCAL_MACHINE/Software/MyApplication
710 \i HKEY_CURRENT_USER/Software/MyApplication 757 \i HKEY_CURRENT_USER/Software/MyApplication
711 \endlist 758 \endlist
712 If a setting is found in the HKEY_CURRENT_USER space, this setting 759 If a setting is found in the HKEY_CURRENT_USER space, this setting
713 is overwritten independently of write permissions in the 760 is overwritten independently of write permissions in the
714 HKEY_LOCAL_MACHINE space. 761 HKEY_LOCAL_MACHINE space.
715 762
716 When \a s is \e Unix, and the execution environment is Unix, the 763 When \a s is \e Unix, and the execution environment is Unix, the
717 search path list will be used when trying to determine a suitable 764 search path list will be used when trying to determine a suitable
718 filename for reading and writing settings files. By default, there are 765 filename for reading and writing settings files. By default, there are
719 two entries in the search path: 766 two entries in the search path:
@@ -754,40 +801,55 @@ static inline QString groupKey( const QString &group, const QString &key )
754 801
755 \sa removeSearchPath() 802 \sa removeSearchPath()
756 803
757*/ 804*/
758void QSettings::insertSearchPath( System s, const QString &path) 805void QSettings::insertSearchPath( System s, const QString &path)
759{ 806{
760#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 807#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
761 if ( d->sysd ) { 808 if ( d->sysd ) {
762 d->sysInsertSearchPath( s, path ); 809 d->sysInsertSearchPath( s, path );
763 return; 810 return;
764 } 811 }
765#endif 812#endif
766 813
767 if ( !verifyKey( path ) ) { 814#if !defined(Q_WS_WIN)
815 if ( s == Windows )
816 return;
817#endif
818#if !defined(Q_WS_WIN)
819 if ( s == Mac )
820 return;
821#endif
822
823 if ( !qt_verify_key( path ) ) {
768#if defined(QT_CHECK_STATE) 824#if defined(QT_CHECK_STATE)
769 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); 825 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
770#endif 826#endif
771 return; 827 return;
772 } 828 }
773 829
774#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 830#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
775 if ( d->sysd && s != Unix ) { 831 if ( d->sysd && s != Unix ) {
776#else 832#else
777 if ( s != Unix ) { 833 if ( s != Unix ) {
778#endif 834#endif
779#ifdef Q_OS_MAC 835#if !defined(QWS) && defined(Q_OS_MAC)
780 if(s != Mac) //mac is respected on the mac as well 836 if(s != Mac) //mac is respected on the mac as well
781#endif 837#endif
782 return; 838 return;
783 } 839 }
784 840
841 QString realPath = path;
842#if defined(Q_WS_WIN)
843 QString defPath = d->globalScope ? d->searchPaths.first() : d->searchPaths.last();
844 realPath = defPath + path;
845#endif
846
785 QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last()); 847 QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last());
786 if (it != d->searchPaths.end()) { 848 if (it != d->searchPaths.end()) {
787 d->searchPaths.insert(it, path); 849 d->searchPaths.insert(it, realPath);
788 } 850 }
789} 851}
790 852
791 853
792/*! 854/*!
793 Removes all occurrences of \a path (using exact matching) from the 855 Removes all occurrences of \a path (using exact matching) from the
@@ -795,31 +857,31 @@ void QSettings::insertSearchPath( System s, const QString &path)
795 paths cannot be removed. 857 paths cannot be removed.
796 858
797 \sa insertSearchPath() 859 \sa insertSearchPath()
798*/ 860*/
799void QSettings::removeSearchPath( System s, const QString &path) 861void QSettings::removeSearchPath( System s, const QString &path)
800{ 862{
801 if ( !verifyKey( path ) ) { 863 if ( !qt_verify_key( path ) ) {
802#if defined(QT_CHECK_STATE) 864#if defined(QT_CHECK_STATE)
803 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); 865 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
804#endif 866#endif
805 return; 867 return;
806 } 868 }
807 869
808#ifdef Q_WS_WIN 870#ifdef Q_WS_WIN
809 if ( d->sysd ) { 871 if ( d->sysd ) {
810 d->sysRemoveSearchPath( s, path ); 872 d->sysRemoveSearchPath( s, path );
811 return; 873 return;
812 } 874 }
813#endif 875#endif
814#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 876#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
815 if ( d->sysd && s != Unix ) { 877 if ( d->sysd && s != Unix ) {
816#else 878#else
817 if ( s != Unix ) { 879 if ( s != Unix ) {
818#endif 880#endif
819#ifdef Q_OS_MAC 881#if !defined(QWS) && defined(Q_OS_MAC)
820 if(s != Mac) //mac is respected on the mac as well 882 if(s != Mac) //mac is respected on the mac as well
821#endif 883#endif
822 return; 884 return;
823 } 885 }
824 886
825 if (path == d->searchPaths.first() || path == d->searchPaths.last()) 887 if (path == d->searchPaths.first() || path == d->searchPaths.last())
@@ -834,13 +896,13 @@ void QSettings::removeSearchPath( System s, const QString &path)
834*/ 896*/
835QSettings::QSettings() 897QSettings::QSettings()
836{ 898{
837 d = new QSettingsPrivate( Native ); 899 d = new QSettingsPrivate( Native );
838 Q_CHECK_PTR(d); 900 Q_CHECK_PTR(d);
839 901
840#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 902#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
841 d->sysd = 0; 903 d->sysd = 0;
842 d->sysInit(); 904 d->sysInit();
843#endif 905#endif
844} 906}
845 907
846/*! 908/*!
@@ -851,13 +913,13 @@ QSettings::QSettings()
851*/ 913*/
852QSettings::QSettings( Format format ) 914QSettings::QSettings( Format format )
853{ 915{
854 d = new QSettingsPrivate( format ); 916 d = new QSettingsPrivate( format );
855 Q_CHECK_PTR(d); 917 Q_CHECK_PTR(d);
856 918
857#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 919#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
858 d->sysd = 0; 920 d->sysd = 0;
859 if ( format == Native ) 921 if ( format == Native )
860 d->sysInit(); 922 d->sysInit();
861#else 923#else
862 Q_UNUSED(format); 924 Q_UNUSED(format);
863#endif 925#endif
@@ -869,13 +931,13 @@ QSettings::QSettings( Format format )
869 931
870*/ 932*/
871QSettings::~QSettings() 933QSettings::~QSettings()
872{ 934{
873 sync(); 935 sync();
874 936
875#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 937#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
876 if ( d->sysd ) 938 if ( d->sysd )
877 d->sysClear(); 939 d->sysClear();
878#endif 940#endif
879 941
880 delete d; 942 delete d;
881} 943}
@@ -884,13 +946,13 @@ QSettings::~QSettings()
884/*! \internal 946/*! \internal
885 Writes all modifications to the settings to disk. If any errors are 947 Writes all modifications to the settings to disk. If any errors are
886 encountered, this function returns FALSE, otherwise it will return TRUE. 948 encountered, this function returns FALSE, otherwise it will return TRUE.
887*/ 949*/
888bool QSettings::sync() 950bool QSettings::sync()
889{ 951{
890#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 952#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
891 if ( d->sysd ) 953 if ( d->sysd )
892 return d->sysSync(); 954 return d->sysSync();
893#endif 955#endif
894 if (! d->modified) 956 if (! d->modified)
895 // fake success 957 // fake success
896 return TRUE; 958 return TRUE;
@@ -902,27 +964,29 @@ bool QSettings::sync()
902 // determine filename 964 // determine filename
903 QSettingsHeading hd(*it); 965 QSettingsHeading hd(*it);
904 QSettingsHeading::Iterator hdit = hd.begin(); 966 QSettingsHeading::Iterator hdit = hd.begin();
905 QFile file; 967 QFile file;
906 968
907 QStringList::Iterator pit = d->searchPaths.begin(); 969 QStringList::Iterator pit = d->searchPaths.begin();
970 if ( !d->globalScope )
971 ++pit;
908 while (pit != d->searchPaths.end()) { 972 while (pit != d->searchPaths.end()) {
909 QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_"); 973 QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_");
910 QFileInfo di(*pit); 974 QFileInfo di(*pit);
911 QFileInfo fi((*pit++) + "/" + filebase + "rc"); 975 QFileInfo fi((*pit++) + "/" + filebase + "rc");
912 976
913 if ((fi.exists() && fi.isFile() && fi.isWritable()) || 977 if ((fi.exists() && fi.isFile() && fi.isWritable()) ||
914 (! fi.exists() && di.isDir() && di.isWritable())) { 978 (! fi.exists() && di.isDir() && di.isWritable())) {
915 file.setName(fi.filePath()); 979 file.setName(fi.filePath());
916 break; 980 break;
917 } 981 }
918 } 982 }
919 983
920 it++; 984 ++it;
921 985
922 if (file.name().isNull() || file.name().isEmpty()) { 986 if ( file.name().isEmpty() ) {
923 987
924#ifdef QT_CHECK_STATE 988#ifdef QT_CHECK_STATE
925 qWarning("QSettings::sync: filename is null/empty"); 989 qWarning("QSettings::sync: filename is null/empty");
926#endif // QT_CHECK_STATE 990#endif // QT_CHECK_STATE
927 991
928 success = FALSE; 992 success = FALSE;
@@ -960,19 +1024,19 @@ bool QSettings::sync()
960 } else { 1024 } else {
961 v.replace("\\", "\\\\"); // escape backslash 1025 v.replace("\\", "\\\\"); // escape backslash
962 v.replace("\n", "\\n"); // escape newlines 1026 v.replace("\n", "\\n"); // escape newlines
963 } 1027 }
964 1028
965 stream << grpit.key() << "=" << v << endl; 1029 stream << grpit.key() << "=" << v << endl;
966 grpit++; 1030 ++grpit;
967 } 1031 }
968 1032
969 stream << endl; 1033 stream << endl;
970 } 1034 }
971 1035
972 hdit++; 1036 ++hdit;
973 } 1037 }
974 1038
975 if (file.status() != IO_Ok) { 1039 if (file.status() != IO_Ok) {
976 1040
977#ifdef QT_CHECK_STATE 1041#ifdef QT_CHECK_STATE
978 qWarning("QSettings::sync: error at end of write"); 1042 qWarning("QSettings::sync: error at end of write");
@@ -1005,29 +1069,28 @@ bool QSettings::sync()
1005 1069
1006/*! 1070/*!
1007 \internal 1071 \internal
1008*/ 1072*/
1009bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) 1073bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok )
1010{ 1074{
1011 if ( !verifyKey( key ) ) { 1075 if ( !qt_verify_key( key ) ) {
1012#if defined(QT_CHECK_STATE) 1076#if defined(QT_CHECK_STATE)
1013 qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1077 qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1014#endif 1078#endif
1015 if ( ok ) 1079 if ( ok )
1016 *ok = FALSE; 1080 *ok = FALSE;
1017 1081
1018 return def; 1082 return def;
1019 } 1083 }
1020 1084
1021 QString theKey = groupKey( group(), key ); 1085#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1022#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1023 if ( d->sysd ) 1086 if ( d->sysd )
1024 return d->sysReadBoolEntry( theKey, def, ok ); 1087 return d->sysReadBoolEntry( groupKey( group(), key ), def, ok );
1025#endif 1088#endif
1026 1089
1027 QString value = readEntry( theKey, ( def ? "true" : "false" ), ok ); 1090 QString value = readEntry( key, ( def ? "true" : "false" ), ok );
1028 1091
1029 if (value.lower() == "true") 1092 if (value.lower() == "true")
1030 return TRUE; 1093 return TRUE;
1031 else if (value.lower() == "false") 1094 else if (value.lower() == "false")
1032 return FALSE; 1095 return FALSE;
1033 else if (value == "1") 1096 else if (value == "1")
@@ -1057,29 +1120,28 @@ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok )
1057 1120
1058/*! 1121/*!
1059 \internal 1122 \internal
1060*/ 1123*/
1061double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) 1124double QSettings::readDoubleEntry(const QString &key, double def, bool *ok )
1062{ 1125{
1063 if ( !verifyKey( key ) ) { 1126 if ( !qt_verify_key( key ) ) {
1064#if defined(QT_CHECK_STATE) 1127#if defined(QT_CHECK_STATE)
1065 qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1128 qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1066#endif 1129#endif
1067 if ( ok ) 1130 if ( ok )
1068 *ok = FALSE; 1131 *ok = FALSE;
1069 1132
1070 return def; 1133 return def;
1071 } 1134 }
1072 1135
1073 QString theKey = groupKey( group(), key ); 1136#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1074#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1075 if ( d->sysd ) 1137 if ( d->sysd )
1076 return d->sysReadDoubleEntry( theKey, def, ok ); 1138 return d->sysReadDoubleEntry( groupKey( group(), key ), def, ok );
1077#endif 1139#endif
1078 1140
1079 QString value = readEntry( theKey, QString::number(def), ok ); 1141 QString value = readEntry( key, QString::number(def), ok );
1080 bool conv_ok; 1142 bool conv_ok;
1081 double retval = value.toDouble( &conv_ok ); 1143 double retval = value.toDouble( &conv_ok );
1082 if ( conv_ok ) 1144 if ( conv_ok )
1083 return retval; 1145 return retval;
1084 if ( ! value.isEmpty() ) 1146 if ( ! value.isEmpty() )
1085 qWarning( "QSettings::readDoubleEntry: '%s' is not a number", 1147 qWarning( "QSettings::readDoubleEntry: '%s' is not a number",
@@ -1103,29 +1165,27 @@ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok )
1103 1165
1104/*! 1166/*!
1105 \internal 1167 \internal
1106*/ 1168*/
1107int QSettings::readNumEntry(const QString &key, int def, bool *ok ) 1169int QSettings::readNumEntry(const QString &key, int def, bool *ok )
1108{ 1170{
1109 if ( !verifyKey( key ) ) { 1171 if ( !qt_verify_key( key ) ) {
1110#if defined(QT_CHECK_STATE) 1172#if defined(QT_CHECK_STATE)
1111 qWarning( "QSettings::readNumEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1173 qWarning( "QSettings::readNumEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1112#endif 1174#endif
1113 if ( ok ) 1175 if ( ok )
1114 *ok = FALSE; 1176 *ok = FALSE;
1115 return def; 1177 return def;
1116 } 1178 }
1117 1179
1118 QString theKey = groupKey( group(), key ); 1180#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1119
1120#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1121 if ( d->sysd ) 1181 if ( d->sysd )
1122 return d->sysReadNumEntry( theKey, def, ok ); 1182 return d->sysReadNumEntry( groupKey( group(), key ), def, ok );
1123#endif 1183#endif
1124 1184
1125 QString value = readEntry( theKey, QString::number( def ), ok ); 1185 QString value = readEntry( key, QString::number( def ), ok );
1126 bool conv_ok; 1186 bool conv_ok;
1127 int retval = value.toInt( &conv_ok ); 1187 int retval = value.toInt( &conv_ok );
1128 if ( conv_ok ) 1188 if ( conv_ok )
1129 return retval; 1189 return retval;
1130 if ( ! value.isEmpty() ) 1190 if ( ! value.isEmpty() )
1131 qWarning( "QSettings::readNumEntry: '%s' is not a number", 1191 qWarning( "QSettings::readNumEntry: '%s' is not a number",
@@ -1149,25 +1209,25 @@ int QSettings::readNumEntry(const QString &key, int def, bool *ok )
1149 1209
1150/*! 1210/*!
1151 \internal 1211 \internal
1152*/ 1212*/
1153QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) 1213QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1154{ 1214{
1155 if ( !verifyKey( key ) ) { 1215 if ( !qt_verify_key( key ) ) {
1156#if defined(QT_CHECK_STATE) 1216#if defined(QT_CHECK_STATE)
1157 qWarning( "QSettings::readEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1217 qWarning( "QSettings::readEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1158#endif 1218#endif
1159 if ( ok ) 1219 if ( ok )
1160 *ok = FALSE; 1220 *ok = FALSE;
1161 1221
1162 return def; 1222 return def;
1163 } 1223 }
1164 1224
1165 QString theKey = groupKey( group(), key ); 1225 QString theKey = groupKey( group(), key );
1166 1226
1167#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1227#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1168 if ( d->sysd ) 1228 if ( d->sysd )
1169 return d->sysReadEntry( theKey, def, ok ); 1229 return d->sysReadEntry( theKey, def, ok );
1170#endif 1230#endif
1171 1231
1172 if ( ok ) // no, everything is not ok 1232 if ( ok ) // no, everything is not ok
1173 *ok = FALSE; 1233 *ok = FALSE;
@@ -1203,17 +1263,19 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1203 realkey = list.join("/"); 1263 realkey = list.join("/");
1204 } 1264 }
1205 } else 1265 } else
1206 realkey = theKey; 1266 realkey = theKey;
1207 1267
1208 QSettingsGroup grp = d->readGroup(); 1268 QSettingsGroup grp = d->readGroup();
1209 QString retval = grp[realkey]; 1269 QSettingsGroup::const_iterator it = grp.find( realkey ), end = grp.end();
1210 if ( retval.isNull() ) 1270 QString retval = def;
1211 retval = def; 1271 if ( it != end ) {
1212 else if ( ok ) // everything is ok 1272 // found the value we needed
1213 *ok = TRUE; 1273 retval = *it;
1274 if ( ok ) *ok = TRUE;
1275 }
1214 return retval; 1276 return retval;
1215} 1277}
1216 1278
1217 1279
1218#if !defined(Q_NO_BOOL_TYPE) 1280#if !defined(Q_NO_BOOL_TYPE)
1219/*! 1281/*!
@@ -1225,27 +1287,25 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1225 returned; otherwise TRUE is returned. 1287 returned; otherwise TRUE is returned.
1226 1288
1227 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1289 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1228*/ 1290*/
1229bool QSettings::writeEntry(const QString &key, bool value) 1291bool QSettings::writeEntry(const QString &key, bool value)
1230{ 1292{
1231 if ( !verifyKey( key ) ) { 1293 if ( !qt_verify_key( key ) ) {
1232#if defined(QT_CHECK_STATE) 1294#if defined(QT_CHECK_STATE)
1233 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1295 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1234#endif 1296#endif
1235 return FALSE; 1297 return FALSE;
1236 } 1298 }
1237 1299
1238 QString theKey = groupKey( group(), key ); 1300#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1239
1240#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1241 if ( d->sysd ) 1301 if ( d->sysd )
1242 return d->sysWriteEntry( theKey, value ); 1302 return d->sysWriteEntry( groupKey( group(), key ), value );
1243#endif 1303#endif
1244 QString s(value ? "true" : "false"); 1304 QString s(value ? "true" : "false");
1245 return writeEntry(theKey, s); 1305 return writeEntry(key, s);
1246} 1306}
1247#endif 1307#endif
1248 1308
1249 1309
1250/*! 1310/*!
1251 \overload 1311 \overload
@@ -1257,27 +1317,25 @@ bool QSettings::writeEntry(const QString &key, bool value)
1257 returned; otherwise TRUE is returned. 1317 returned; otherwise TRUE is returned.
1258 1318
1259 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1319 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1260*/ 1320*/
1261bool QSettings::writeEntry(const QString &key, double value) 1321bool QSettings::writeEntry(const QString &key, double value)
1262{ 1322{
1263 if ( !verifyKey( key ) ) { 1323 if ( !qt_verify_key( key ) ) {
1264#if defined(QT_CHECK_STATE) 1324#if defined(QT_CHECK_STATE)
1265 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1325 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1266#endif 1326#endif
1267 return FALSE; 1327 return FALSE;
1268 } 1328 }
1269 1329
1270 QString theKey = groupKey( group(), key ); 1330#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1271
1272#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1273 if ( d->sysd ) 1331 if ( d->sysd )
1274 return d->sysWriteEntry( theKey, value ); 1332 return d->sysWriteEntry( groupKey( group(), key ), value );
1275#endif 1333#endif
1276 QString s(QString::number(value)); 1334 QString s(QString::number(value));
1277 return writeEntry(theKey, s); 1335 return writeEntry(key, s);
1278} 1336}
1279 1337
1280 1338
1281/*! 1339/*!
1282 \overload 1340 \overload
1283 Writes the integer entry \a value into key \a key. The \a key is 1341 Writes the integer entry \a value into key \a key. The \a key is
@@ -1288,27 +1346,25 @@ bool QSettings::writeEntry(const QString &key, double value)
1288 returned; otherwise TRUE is returned. 1346 returned; otherwise TRUE is returned.
1289 1347
1290 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1348 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1291*/ 1349*/
1292bool QSettings::writeEntry(const QString &key, int value) 1350bool QSettings::writeEntry(const QString &key, int value)
1293{ 1351{
1294 if ( !verifyKey( key ) ) { 1352 if ( !qt_verify_key( key ) ) {
1295#if defined(QT_CHECK_STATE) 1353#if defined(QT_CHECK_STATE)
1296 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1354 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1297#endif 1355#endif
1298 return FALSE; 1356 return FALSE;
1299 } 1357 }
1300 1358
1301 QString theKey = groupKey( group(), key ); 1359#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1302
1303#if defined(Q_WS_WIN) || defined(Q_OS_MAC)
1304 if ( d->sysd ) 1360 if ( d->sysd )
1305 return d->sysWriteEntry( theKey, value ); 1361 return d->sysWriteEntry( groupKey( group(), key ), value );
1306#endif 1362#endif
1307 QString s(QString::number(value)); 1363 QString s(QString::number(value));
1308 return writeEntry(theKey, s); 1364 return writeEntry(key, s);
1309} 1365}
1310 1366
1311 1367
1312/*! 1368/*!
1313 \internal 1369 \internal
1314 1370
@@ -1324,22 +1380,20 @@ bool QSettings::writeEntry(const QString &key, int value)
1324 unchanged. 1380 unchanged.
1325 1381
1326 \sa readEntry(), removeEntry() 1382 \sa readEntry(), removeEntry()
1327*/ 1383*/
1328bool QSettings::writeEntry(const QString &key, const char *value) 1384bool QSettings::writeEntry(const QString &key, const char *value)
1329{ 1385{
1330 if ( !verifyKey( key ) ) { 1386 if ( !qt_verify_key( key ) ) {
1331#if defined(QT_CHECK_STATE) 1387#if defined(QT_CHECK_STATE)
1332 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1388 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1333#endif 1389#endif
1334 return FALSE; 1390 return FALSE;
1335 } 1391 }
1336 1392
1337 QString theKey = groupKey( group(), key ); 1393 return writeEntry(key, QString(value));
1338
1339 return writeEntry(theKey, QString(value));
1340} 1394}
1341 1395
1342 1396
1343/*! 1397/*!
1344 \overload 1398 \overload
1345 Writes the string entry \a value into key \a key. The \a key is 1399 Writes the string entry \a value into key \a key. The \a key is
@@ -1351,22 +1405,22 @@ bool QSettings::writeEntry(const QString &key, const char *value)
1351 returned; otherwise TRUE is returned. 1405 returned; otherwise TRUE is returned.
1352 1406
1353 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1407 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1354*/ 1408*/
1355bool QSettings::writeEntry(const QString &key, const QString &value) 1409bool QSettings::writeEntry(const QString &key, const QString &value)
1356{ 1410{
1357 if ( !verifyKey( key ) ) { 1411 if ( !qt_verify_key( key ) ) {
1358#if defined(QT_CHECK_STATE) 1412#if defined(QT_CHECK_STATE)
1359 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1413 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1360#endif 1414#endif
1361 return FALSE; 1415 return FALSE;
1362 } 1416 }
1363 1417
1364 QString theKey = groupKey( group(), key ); 1418 QString theKey = groupKey( group(), key );
1365 1419
1366#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1420#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1367 if ( d->sysd ) 1421 if ( d->sysd )
1368 return d->sysWriteEntry( theKey, value ); 1422 return d->sysWriteEntry( theKey, value );
1369#endif 1423#endif
1370 // NOTE: we *do* allow value to be a null/empty string 1424 // NOTE: we *do* allow value to be a null/empty string
1371 1425
1372 QString realkey; 1426 QString realkey;
@@ -1412,22 +1466,22 @@ bool QSettings::writeEntry(const QString &key, const QString &value)
1412 Returns TRUE if the entry existed and was removed; otherwise returns FALSE. 1466 Returns TRUE if the entry existed and was removed; otherwise returns FALSE.
1413 1467
1414 \sa readEntry(), writeEntry() 1468 \sa readEntry(), writeEntry()
1415*/ 1469*/
1416bool QSettings::removeEntry(const QString &key) 1470bool QSettings::removeEntry(const QString &key)
1417{ 1471{
1418 if ( !verifyKey( key ) ) { 1472 if ( !qt_verify_key( key ) ) {
1419#if defined(QT_CHECK_STATE) 1473#if defined(QT_CHECK_STATE)
1420 qWarning( "QSettings::removeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1474 qWarning( "QSettings::removeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1421#endif 1475#endif
1422 return FALSE; 1476 return FALSE;
1423 } 1477 }
1424 1478
1425 QString theKey = groupKey( group(), key ); 1479 QString theKey = groupKey( group(), key );
1426 1480
1427#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1481#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1428 if ( d->sysd ) 1482 if ( d->sysd )
1429 return d->sysRemoveEntry( theKey ); 1483 return d->sysRemoveEntry( theKey );
1430#endif 1484#endif
1431 1485
1432 QString realkey; 1486 QString realkey;
1433 1487
@@ -1491,22 +1545,22 @@ bool QSettings::removeEntry(const QString &key)
1491 "/MyCompany/MyApplication/geometry/y". 1545 "/MyCompany/MyApplication/geometry/y".
1492 1546
1493 \sa subkeyList() 1547 \sa subkeyList()
1494*/ 1548*/
1495QStringList QSettings::entryList(const QString &key) const 1549QStringList QSettings::entryList(const QString &key) const
1496{ 1550{
1497 if ( !verifyKey( key ) ) { 1551 if ( !qt_verify_key( key ) ) {
1498#if defined(QT_CHECK_STATE) 1552#if defined(QT_CHECK_STATE)
1499 qWarning( "QSettings::entryList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); 1553 qWarning( "QSettings::entryList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() );
1500#endif 1554#endif
1501 return QStringList(); 1555 return QStringList();
1502 } 1556 }
1503 1557
1504 QString theKey = groupKey( group(), key ); 1558 QString theKey = groupKey( group(), key );
1505 1559
1506#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1560#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1507 if ( d->sysd ) 1561 if ( d->sysd )
1508 return d->sysEntryList( theKey ); 1562 return d->sysEntryList( theKey );
1509#endif 1563#endif
1510 1564
1511 QString realkey; 1565 QString realkey;
1512 if (theKey[0] == '/') { 1566 if (theKey[0] == '/') {
@@ -1541,13 +1595,13 @@ QStringList QSettings::entryList(const QString &key) const
1541 QSettingsGroup grp = d->readGroup(); 1595 QSettingsGroup grp = d->readGroup();
1542 QSettingsGroup::Iterator it = grp.begin(); 1596 QSettingsGroup::Iterator it = grp.begin();
1543 QStringList ret; 1597 QStringList ret;
1544 QString itkey; 1598 QString itkey;
1545 while (it != grp.end()) { 1599 while (it != grp.end()) {
1546 itkey = it.key(); 1600 itkey = it.key();
1547 it++; 1601 ++it;
1548 1602
1549 if ( realkey.length() > 0 ) { 1603 if ( realkey.length() > 0 ) {
1550 if ( itkey.left( realkey.length() ) != realkey ) 1604 if ( itkey.left( realkey.length() ) != realkey )
1551 continue; 1605 continue;
1552 else 1606 else
1553 itkey.remove( 0, realkey.length() + 1 ); 1607 itkey.remove( 0, realkey.length() + 1 );
@@ -1588,39 +1642,42 @@ QStringList QSettings::entryList(const QString &key) const
1588 rather than subkeys use entryList(). 1642 rather than subkeys use entryList().
1589 1643
1590 \sa entryList() 1644 \sa entryList()
1591*/ 1645*/
1592QStringList QSettings::subkeyList(const QString &key) const 1646QStringList QSettings::subkeyList(const QString &key) const
1593{ 1647{
1594 if ( !verifyKey( key ) ) { 1648 if ( !qt_verify_key( key ) ) {
1595#if defined(QT_CHECK_STATE) 1649#if defined(QT_CHECK_STATE)
1596 qWarning( "QSettings::subkeyList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); 1650 qWarning( "QSettings::subkeyList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() );
1597#endif 1651#endif
1598 return QStringList(); 1652 return QStringList();
1599 } 1653 }
1600 1654
1601 QString theKey = groupKey( group(), key ); 1655 QString theKey = groupKey( group(), key );
1602 1656
1603#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1657#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1604 if ( d->sysd ) 1658 if ( d->sysd )
1605 return d->sysSubkeyList( theKey ); 1659 return d->sysSubkeyList( theKey );
1606#endif 1660#endif
1607 1661
1608 QString realkey; 1662 QString realkey;
1663 int subkeycount = 2;
1609 if (theKey[0] == '/') { 1664 if (theKey[0] == '/') {
1610 // parse our key 1665 // parse our key
1611 QStringList list(QStringList::split('/', theKey)); 1666 QStringList list(QStringList::split('/', theKey));
1612 1667
1613 if (list.count() < 1) { 1668 if (list.count() < 1) {
1614#ifdef QT_CHECK_STATE 1669#ifdef QT_CHECK_STATE
1615 qWarning("QSettings::subkeyList: invalid key '%s'", theKey.latin1()); 1670 qWarning("QSettings::subkeyList: invalid key '%s'", theKey.latin1());
1616#endif // QT_CHECK_STATE 1671#endif // QT_CHECK_STATE
1617 1672
1618 return QStringList(); 1673 return QStringList();
1619 } 1674 }
1620 1675
1676 subkeycount = list.count();
1677
1621 if (list.count() == 1) { 1678 if (list.count() == 1) {
1622 d->heading = list[0]; 1679 d->heading = list[0];
1623 d->group = "General"; 1680 d->group = "General";
1624 } else { 1681 } else {
1625 d->heading = list[0]; 1682 d->heading = list[0];
1626 d->group = list[1]; 1683 d->group = list[1];
@@ -1629,22 +1686,34 @@ QStringList QSettings::subkeyList(const QString &key) const
1629 list.remove(list.at(1)); 1686 list.remove(list.at(1));
1630 // remove the heading from the list 1687 // remove the heading from the list
1631 list.remove(list.at(0)); 1688 list.remove(list.at(0));
1632 1689
1633 realkey = list.join("/"); 1690 realkey = list.join("/");
1634 } 1691 }
1692
1635 } else 1693 } else
1636 realkey = theKey; 1694 realkey = theKey;
1637 1695
1696 QStringList ret;
1697 if ( subkeycount == 1 ) {
1698 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin();
1699 while ( it != d->headings.end() ) {
1700 if ( it.key() != "General" && ! ret.contains( it.key() ) )
1701 ret << it.key();
1702 ++it;
1703 }
1704
1705 return ret;
1706 }
1707
1638 QSettingsGroup grp = d->readGroup(); 1708 QSettingsGroup grp = d->readGroup();
1639 QSettingsGroup::Iterator it = grp.begin(); 1709 QSettingsGroup::Iterator it = grp.begin();
1640 QStringList ret;
1641 QString itkey; 1710 QString itkey;
1642 while (it != grp.end()) { 1711 while (it != grp.end()) {
1643 itkey = it.key(); 1712 itkey = it.key();
1644 it++; 1713 ++it;
1645 1714
1646 if ( realkey.length() > 0 ) { 1715 if ( realkey.length() > 0 ) {
1647 if ( itkey.left( realkey.length() ) != realkey ) 1716 if ( itkey.left( realkey.length() ) != realkey )
1648 continue; 1717 continue;
1649 else 1718 else
1650 itkey.remove( 0, realkey.length() + 1 ); 1719 itkey.remove( 0, realkey.length() + 1 );
@@ -1667,22 +1736,22 @@ QStringList QSettings::subkeyList(const QString &key) const
1667 \internal 1736 \internal
1668 1737
1669 This function returns the time of last modification for \a key. 1738 This function returns the time of last modification for \a key.
1670*/ 1739*/
1671QDateTime QSettings::lastModficationTime(const QString &key) 1740QDateTime QSettings::lastModficationTime(const QString &key)
1672{ 1741{
1673 if ( !verifyKey( key ) ) { 1742 if ( !qt_verify_key( key ) ) {
1674#if defined(QT_CHECK_STATE) 1743#if defined(QT_CHECK_STATE)
1675 qWarning( "QSettings::lastModficationTime: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1744 qWarning( "QSettings::lastModficationTime: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1676#endif 1745#endif
1677 return QDateTime(); 1746 return QDateTime();
1678 } 1747 }
1679 1748
1680 QString theKey = groupKey( group(), key ); 1749 QString theKey = groupKey( group(), key );
1681 1750
1682#if defined(Q_WS_WIN) || defined(Q_OS_MAC) 1751#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1683 if ( d->sysd ) 1752 if ( d->sysd )
1684 return QDateTime(); 1753 return QDateTime();
1685#endif 1754#endif
1686 1755
1687 if (theKey[0] == '/') { 1756 if (theKey[0] == '/') {
1688 // parse our key 1757 // parse our key
@@ -1712,15 +1781,23 @@ QDateTime QSettings::lastModficationTime(const QString &key)
1712/*! 1781/*!
1713 \overload 1782 \overload
1714 1783
1715 Writes the string list entry \a value into key \a key. The \a key 1784 Writes the string list entry \a value into key \a key. The \a key
1716 is created if it doesn't exist. Any previous value is overwritten 1785 is created if it doesn't exist. Any previous value is overwritten
1717 by \a value. The list is stored as a sequence of strings separated 1786 by \a value. The list is stored as a sequence of strings separated
1718 by \a separator, so none of the strings in the list should contain 1787 by \a separator (using QStringList::join()), so none of the
1719 the separator. If the list is empty or null the key's value will 1788 strings in the list should contain the separator. If the list is
1720 be an empty string. 1789 empty or null the key's value will be an empty string.
1790
1791 \warning The list should not contain empty or null strings, as
1792 readListEntry() will use QStringList::split() to recreate the
1793 list. As the documentation states, QStringList::split() will omit
1794 empty strings from the list. Because of this, it is impossible to
1795 retrieve identical list data that is stored with this function.
1796 We recommend using the writeEntry() and readListEntry() overloads
1797 that do not take a \a separator argument.
1721 1798
1722 If an error occurs the settings are left unchanged and FALSE is 1799 If an error occurs the settings are left unchanged and FALSE is
1723 returned; otherwise returns TRUE. 1800 returned; otherwise returns TRUE.
1724 1801
1725 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1802 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1726*/ 1803*/
@@ -1765,12 +1842,19 @@ bool QSettings::writeEntry(const QString &key, const QStringList &value)
1765 1842
1766 Reads the entry specified by \a key as a string. The \a separator 1843 Reads the entry specified by \a key as a string. The \a separator
1767 is used to create a QStringList by calling QStringList::split(\a 1844 is used to create a QStringList by calling QStringList::split(\a
1768 separator, entry). If \a ok is not 0: \a *ok is set to TRUE if the 1845 separator, entry). If \a ok is not 0: \a *ok is set to TRUE if the
1769 key was read, otherwise \a *ok is set to FALSE. 1846 key was read, otherwise \a *ok is set to FALSE.
1770 1847
1848 \warning As the documentation states, QStringList::split() will
1849 omit empty strings from the list. Because of this, it is
1850 impossible to retrieve identical list data with this function. We
1851 recommend using the readListEntry() and writeEntry() overloads
1852 that do not take a \a separator argument.
1853
1854
1771 Note that if you want to iterate over the list, you should iterate 1855 Note that if you want to iterate over the list, you should iterate
1772 over a copy, e.g. 1856 over a copy, e.g.
1773 \code 1857 \code
1774 QStringList list = mySettings.readListEntry( "size", " " ); 1858 QStringList list = mySettings.readListEntry( "size", " " );
1775 QStringList::Iterator it = list.begin(); 1859 QStringList::Iterator it = list.begin();
1776 while( it != list.end() ) { 1860 while( it != list.end() ) {
@@ -1844,25 +1928,32 @@ QStringList QSettings::readListEntry(const QString &key, bool *ok )
1844 l.append(s); 1928 l.append(s);
1845 } 1929 }
1846 } 1930 }
1847 return l; 1931 return l;
1848} 1932}
1849 1933
1934#ifdef Q_OS_MAC
1935void qt_setSettingsBasePath(const QString &); //qsettings_mac.cpp
1936#endif
1937
1850/*! 1938/*!
1851 Insert platform-dependent paths from platform-independent information. 1939 Insert platform-dependent paths from platform-independent information.
1940
1941 The \a domain should be an Internet domain name
1942 controlled by the producer of the software, eg. Trolltech products
1943 use "trolltech.com".
1852 1944
1853 The \a domain should be an Internet domain name 1945 The \a product should be the official name of the product.
1854 controlled by the producer of the software, eg. Trolltech products
1855 use "trolltech.com".
1856 1946
1857 The \a product should be the official name of the product. 1947 The \a scope should be
1948 QSettings::User for user-specific settings, or
1949 QSettings::Global for system-wide settings (generally
1950 these will be read-only to many users).
1858 1951
1859 The \a scope should be 1952 Not all information is relevant on all systems (e.g. scoping is
1860 QSettings::User for user-specific settings, or 1953 currently used only if QSettings accesses the Windows registry).
1861 QSettings::Global for system-wide settings (generally
1862 these will be read-only to many users).
1863*/ 1954*/
1864 1955
1865void QSettings::setPath( const QString &domain, const QString &product, Scope scope ) 1956void QSettings::setPath( const QString &domain, const QString &product, Scope scope )
1866{ 1957{
1867// On Windows, any trailing ".com(\..*)" is stripped from the domain. The 1958// On Windows, any trailing ".com(\..*)" is stripped from the domain. The
1868// Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to 1959// Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to
@@ -1870,51 +1961,65 @@ void QSettings::setPath( const QString &domain, const QString &product, Scope sc
1870// write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped 1961// write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped
1871// from the domain. The Global scope corresponds to "/opt" (this would be 1962// from the domain. The Global scope corresponds to "/opt" (this would be
1872// configurable at library build time - eg. to "/usr/local" or "/usr"), 1963// configurable at library build time - eg. to "/usr/local" or "/usr"),
1873// while the User scope corresponds to $HOME/.*rc. 1964// while the User scope corresponds to $HOME/.*rc.
1874// Note that on most installations, not all users can write to the System 1965// Note that on most installations, not all users can write to the System
1875// scope. 1966// scope.
1876// 1967//
1877// On MacOS X, if there is no "." in domain, append ".com", then reverse the 1968// On MacOS X, if there is no "." in domain, append ".com", then reverse the
1878// order of the elements (Mac OS uses "com.apple.finder" as domain+product). 1969// order of the elements (Mac OS uses "com.apple.finder" as domain+product).
1879// The Global scope corresponds to /Library/Preferences/*.plist, while the 1970// The Global scope corresponds to /Library/Preferences/*.plist, while the
1880// User scope corresponds to ~/Library/Preferences/*.plist. 1971// User scope corresponds to ~/Library/Preferences/*.plist.
1881// Note that on most installations, not all users can write to the System 1972// Note that on most installations, not all users can write to the System
1882// scope. 1973// scope.
1974 d->globalScope = scope == Global;
1975
1883 QString actualSearchPath; 1976 QString actualSearchPath;
1884 int lastDot = domain.findRev( '.' ); 1977 int lastDot = domain.findRev( '.' );
1885 1978
1886#if defined(Q_WS_WIN) 1979#if defined(Q_WS_WIN)
1887 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; 1980 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product;
1888 insertSearchPath( Windows, actualSearchPath ); 1981 insertSearchPath( Windows, actualSearchPath );
1889#elif defined(Q_WS_MAC) 1982#elif !defined(QWS) && defined(Q_OS_MAC)
1890 QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + "."; 1983 QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + ".";
1891 if ( topLevelDomain.isEmpty() ) 1984 if ( !topLevelDomain.isEmpty() )
1892 topLevelDomain = "com."; 1985 qt_setSettingsBasePath( topLevelDomain );
1893 actualSearchPath = "/" + topLevelDomain + domain.left( lastDot ) + product; 1986 actualSearchPath = "/" + domain.left( lastDot ) + product;
1894 insertSearchPath( Mac, actualSearchPath ); 1987 insertSearchPath( Mac, actualSearchPath );
1895#else 1988#else
1896 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; 1989 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product;
1897 insertSearchPath( Unix, actualSearchPath ); 1990 insertSearchPath( Unix, actualSearchPath );
1898#endif 1991#endif
1899
1900 d->globalScope = scope == Global;
1901} 1992}
1902 1993
1903/*! 1994/*!
1904 Appends \a group to the current key prefix. 1995 Appends \a group to the current key prefix.
1996
1997 \code
1998 QSettings settings;
1999 settings.beginGroup( "/MainWindow" );
2000 // read values
2001 settings.endGroup();
2002 \endcode
1905*/ 2003*/
1906void QSettings::beginGroup( const QString &group ) 2004void QSettings::beginGroup( const QString &group )
1907{ 2005{
1908 d->groupStack.push( group ); 2006 d->groupStack.push( group );
1909 d->groupDirty = TRUE; 2007 d->groupDirty = TRUE;
1910} 2008}
1911 2009
1912/*! 2010/*!
1913 Undo previous calls to beginGroup(). Note that a single beginGroup("a/b/c") is undone 2011 Undo previous calls to beginGroup(). Note that a single beginGroup("a/b/c") is undone
1914 by a single call to endGroup(). 2012 by a single call to endGroup().
2013
2014 \code
2015 QSettings settings;
2016 settings.beginGroup( "/MainWindow/Geometry" );
2017 // read values
2018 settings.endGroup();
2019 \endcode
1915*/ 2020*/
1916void QSettings::endGroup() 2021void QSettings::endGroup()
1917{ 2022{
1918 d->groupStack.pop(); 2023 d->groupStack.pop();
1919 d->groupDirty = TRUE; 2024 d->groupDirty = TRUE;
1920} 2025}
@@ -1942,13 +2047,13 @@ QString QSettings::group() const
1942 2047
1943 QValueStack<QString>::Iterator it = d->groupStack.begin(); 2048 QValueStack<QString>::Iterator it = d->groupStack.begin();
1944 while ( it != d->groupStack.end() ) { 2049 while ( it != d->groupStack.end() ) {
1945 QString group = *it; 2050 QString group = *it;
1946 ++it; 2051 ++it;
1947 if ( group[0] != '/' ) 2052 if ( group[0] != '/' )
1948 group = "/" + group; 2053 group.prepend( "/" );
1949 d->groupPrefix += group; 2054 d->groupPrefix += group;
1950 } 2055 }
1951 } 2056 }
1952 return d->groupPrefix; 2057 return d->groupPrefix;
1953} 2058}
1954 2059