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.cpp371
1 files changed, 191 insertions, 180 deletions
diff --git a/qmake/tools/qsettings.cpp b/qmake/tools/qsettings.cpp
index 35fc039..598e94b 100644
--- a/qmake/tools/qsettings.cpp
+++ b/qmake/tools/qsettings.cpp
@@ -1,16 +1,16 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$ 2**
3** 3**
4** Implementation of QSettings class 4** Implementation of QSettings class
5** 5**
6** Created : 000626 6** Created : 000626
7** 7**
8** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 8** Copyright (C) 2000-2003 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
13** as defined by Trolltech AS of Norway and appearing in the file 13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 14** LICENSE.QPL included in the packaging of this file.
15** 15**
16** This file may be distributed and/or modified under the terms of the 16** This file may be distributed and/or modified under the terms of the
@@ -55,17 +55,19 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
55 55
56#include "qdir.h" 56#include "qdir.h"
57#include "qfile.h" 57#include "qfile.h"
58#include "qfileinfo.h" 58#include "qfileinfo.h"
59#include "qmap.h" 59#include "qmap.h"
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#ifndef NO_ERRNO_H
63#include <errno.h> 64#include <errno.h>
65#endif
64 66
65/*! 67/*!
66 \class QSettings 68 \class QSettings
67 \brief The QSettings class provides persistent platform-independent application settings. 69 \brief The QSettings class provides persistent platform-independent application settings.
68 70
69 \ingroup io 71 \ingroup io
70 \ingroup misc 72 \ingroup misc
71 \mainclass 73 \mainclass
@@ -96,38 +98,41 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
96 /MyCompany/MyApplication/geometry/width 98 /MyCompany/MyApplication/geometry/width
97 /MyCompany/MyApplication/geometry/height 99 /MyCompany/MyApplication/geometry/height
98 /MyCompany/MyApplication/recent files/1 100 /MyCompany/MyApplication/recent files/1
99 /MyCompany/MyApplication/recent files/2 101 /MyCompany/MyApplication/recent files/2
100 /MyCompany/MyApplication/recent files/3 102 /MyCompany/MyApplication/recent files/3
101 \endcode 103 \endcode
102 Each line above is a complete key, made up of subkeys. 104 Each line above is a complete key, made up of subkeys.
103 105
104 A typical usage pattern for reading application startup: 106 A typical usage pattern for reading settings at application
107 startup:
105 \code 108 \code
106 QSettings settings; 109 QSettings settings;
107 settings.setPath( "MyCompany.com", "MyApplication" ); 110 settings.setPath( "MyCompany.com", "MyApplication" );
108 111
109 QString bgColor = settings.readEntry( "/colors/background", "white" ); 112 QString bgColor = settings.readEntry( "/colors/background", "white" );
110 int width = settings.readNumEntry( "/geometry/width", 640 ); 113 int width = settings.readNumEntry( "/geometry/width", 640 );
111 // ... 114 // ...
112 \endcode 115 \endcode
113 116
114 A typical usage pattern for application exit or 'save preferences': 117 A typical usage pattern for saving settings at application exit or
118 'save preferences':
115 \code 119 \code
116 QSettings settings; 120 QSettings settings;
117 settings.setPath( "MyCompany.com", "MyApplication" ); 121 settings.setPath( "MyCompany.com", "MyApplication" );
118 122
119 settings.writeEntry( "/colors/background", bgColor ); 123 settings.writeEntry( "/colors/background", bgColor );
120 settings.writeEntry( "/geometry/width", width ); 124 settings.writeEntry( "/geometry/width", width );
121 // ... 125 // ...
122 \endcode 126 \endcode
123 127
124 QSettings can build a key prefix that is prepended to all keys. To 128 A key prefix can be prepended to all keys using beginGroup(). The
125 build the key prefix, use beginGroup() and endGroup(). 129 application of the prefix is stopped using endGroup(). For
130 example:
126 \code 131 \code
127 QSettings settings; 132 QSettings settings;
128 133
129 settings.beginGroup( "/MainWindow" ); 134 settings.beginGroup( "/MainWindow" );
130 settings.beginGroup( "/Geometry" ); 135 settings.beginGroup( "/Geometry" );
131 int x = settings.readEntry( "/x" ); 136 int x = settings.readEntry( "/x" );
132 // ... 137 // ...
133 settings.endGroup(); 138 settings.endGroup();
@@ -149,55 +154,56 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
149 154
150 QStringList subkeys = subkeyList( "/MyApplication" ); 155 QStringList subkeys = subkeyList( "/MyApplication" );
151 // subkeys contains 'geometry' and 'recent files' 156 // subkeys contains 'geometry' and 'recent files'
152 157
153 QStringList subkeys = subkeyList( "/MyApplication/recent files" ); 158 QStringList subkeys = subkeyList( "/MyApplication/recent files" );
154 // subkeys is empty. 159 // subkeys is empty.
155 \endcode 160 \endcode
156 161
157 Since settings for Windows are stored in the registry there are size 162 Since settings for Windows are stored in the registry there are
158 limits as follows: 163 some size limitations as follows:
159 \list 164 \list
160 \i A subkey may not exceed 255 characters. 165 \i A subkey may not exceed 255 characters.
161 \i An entry's value may not exceed 16,300 characters. 166 \i An entry's value may not exceed 16,300 characters.
162 \i All the values of a key (for example, all the 'recent files' 167 \i All the values of a key (for example, all the 'recent files'
163 subkeys values), may not exceed 65,535 characters. 168 subkeys values), may not exceed 65,535 characters.
164 \endlist 169 \endlist
165 170
166 These limitations are not enforced on Unix or Mac OS X. 171 These limitations are not enforced on Unix or Mac OS X.
167 172
168 If you wish to use a different search path call insertSearchPath() 173 \warning Creating multiple, simultaneous instances of QSettings writing
169 as often as necessary to add your preferred paths. Call 174 to a text file may lead to data loss! This is a known issue which will
170 removeSearchPath() to remove any unwanted paths. 175 be fixed in a future release of Qt.
171 176
172 \section1 Notes for Mac OS X Applications 177 \section1 Notes for Mac OS X Applications
173 178
174 Internal to the CFPreferences API it is not defined (for Mac OS 9 179 The location where settings are stored is not formally defined by
175 support) where the settings will ultimitely be stored. However, at the 180 the CFPreferences API.
176 time of this writing the settings will be stored (either on a global or 181
177 user basis, preferring locally) into a plist file in 182 At the time of writing settings are stored (either on a global or
178 $ROOT/System/Library/Preferences (in XML format). QSettings will create 183 user basis, preferring locally) into a plist file in \c
179 an appropriate plist file (com.<first group name>.plist) out of the 184 $ROOT/System/Library/Preferences (in XML format). QSettings will
180 full path to a key. 185 create an appropriate plist file (\c{com.<first group name>.plist})
186 out of the full path to a key.
181 187
182 For further information on CFPreferences see also 188 For further information on CFPreferences see
183 \link http://developer.apple.com/techpubs/macosx/CoreFoundation/PreferenceServices/preferenceservices_carbon.html 189 \link http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFPreferences/index.html
184 Apple's Specifications\endlink 190 Apple's Specifications\endlink
185 191
186 \section1 Notes for Unix Applications 192 \section1 Notes for Unix Applications
187 193
188 There is no universally accepted place for storing application 194 There is no universally accepted place for storing application
189 settings under Unix. In the examples the settings file will be 195 settings under Unix. In the examples the settings file will be
190 searched for in the following directories: 196 searched for in the following directories:
191 \list 1 197 \list 1
192 \i INSTALL/etc/settings 198 \i \c SYSCONF - the default value is \c INSTALL/etc/settings
193 \i /opt/MyCompany/share/etc 199 \i \c /opt/MyCompany/share/etc
194 \i /opt/MyCompany/share/MyApplication/etc 200 \i \c /opt/MyCompany/share/MyApplication/etc
195 \i $HOME/.qt 201 \i \c $HOME/.qt
196 \endlist 202 \endlist
197 When reading settings the files are searched in the order shown 203 When reading settings the files are searched in the order shown
198 above, with later settings overriding earlier settings. Files for 204 above, with later settings overriding earlier settings. Files for
199 which the user doesn't have read permission are ignored. When saving 205 which the user doesn't have read permission are ignored. When saving
200 settings QSettings works in the order shown above, writing 206 settings QSettings works in the order shown above, writing
201 to the first settings file for which the user has write permission. 207 to the first settings file for which the user has write permission.
202 (\c INSTALL is the directory where Qt was installed. This can be 208 (\c INSTALL is the directory where Qt was installed. This can be
203 modified by using the configure script's -prefix argument ) 209 modified by using the configure script's -prefix argument )
@@ -212,18 +218,18 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode )
212 For example the following code: 218 For example the following code:
213 \code 219 \code
214 settings.writeEntry( "/MyApplication/geometry/width", width ); 220 settings.writeEntry( "/MyApplication/geometry/width", width );
215 \endcode 221 \endcode
216 will end up writing the "geometry/width" setting to the file 222 will end up writing the "geometry/width" setting to the file
217 \c{$HOME/.qt/myapplicationrc} (assuming that the application is 223 \c{$HOME/.qt/myapplicationrc} (assuming that the application is
218 being run by an ordinary user, i.e. not by root). 224 being run by an ordinary user, i.e. not by root).
219 225
220 For cross-platform applications you should ensure that the Windows 226 For cross-platform applications you should ensure that the
221 size limitations are not exceeded. 227 \link #sizelimit Windows size limitations \endlink are not exceeded.
222*/ 228*/
223 229
224/*! 230/*!
225 \enum QSettings::System 231 \enum QSettings::System
226 232
227 \value Mac Macintosh execution environments 233 \value Mac Macintosh execution environments
228 \value Unix Mac OS X, Unix, Linux and Unix-like execution environments 234 \value Unix Mac OS X, Unix, Linux and Unix-like execution environments
229 \value Windows Windows execution environments 235 \value Windows Windows execution environments
@@ -305,72 +311,35 @@ static void closelock( HANDLE fd )
305 fl.l_whence = SEEK_SET; 311 fl.l_whence = SEEK_SET;
306 fl.l_start = 0; 312 fl.l_start = 0;
307 fl.l_len = 0; 313 fl.l_len = 0;
308 // ignore the return value, so that the unlock fails silently 314 // ignore the return value, so that the unlock fails silently
309 (void) fcntl( fd, F_SETLKW, &fl ); 315 (void) fcntl( fd, F_SETLKW, &fl );
310 316
311 close( fd ); 317 close( fd );
312} 318}
313#elif defined(Q_WS_WIN)
314#define Q_LOCKREAD 1
315#define Q_LOCKWRITE 2
316
317static HANDLE openlock( const QString &name, int /*type*/ )
318{
319 if ( !QFile::exists( name ) )
320 return 0;
321
322 return 0;
323
324 HANDLE fd = 0;
325
326 QT_WA( {
327 fd = CreateFileW( (TCHAR*)name.ucs2(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
328 } , {
329 fd = CreateFileA( name.local8Bit(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
330 } );
331
332 if ( !LockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ???
333#ifdef QT_CHECK_STATE
334 qWarning( "QSettings: openlock failed!" );
335#endif
336 }
337 return fd;
338}
339
340static void closelock( HANDLE fd )
341{
342 if ( !fd )
343 return;
344
345 if ( !UnlockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ???
346#ifdef QT_CHECK_STATE
347 qWarning( "QSettings: closelock failed!");
348#endif
349 }
350 CloseHandle( fd );
351}
352#endif 319#endif
353 320
354 321
355QSettingsGroup::QSettingsGroup() 322QSettingsGroup::QSettingsGroup()
356 : modified(FALSE) 323 : modified(FALSE)
357{ 324{
358} 325}
359 326
360 327
361 328
362 329
363void QSettingsHeading::read(const QString &filename) 330void QSettingsHeading::read(const QString &filename)
364{ 331{
365 if (! QFileInfo(filename).exists()) 332 if (! QFileInfo(filename).exists())
366 return; 333 return;
367 334
335#ifndef Q_WS_WIN
368 HANDLE lockfd = openlock( filename, Q_LOCKREAD ); 336 HANDLE lockfd = openlock( filename, Q_LOCKREAD );
337#endif
369 338
370 QFile file(filename); 339 QFile file(filename);
371 if (! file.open(IO_ReadOnly)) { 340 if (! file.open(IO_ReadOnly)) {
372#if defined(QT_CHECK_STATE) 341#if defined(QT_CHECK_STATE)
373 qWarning("QSettings: failed to open file '%s'", filename.latin1()); 342 qWarning("QSettings: failed to open file '%s'", filename.latin1());
374#endif 343#endif
375 return; 344 return;
376 } 345 }
@@ -381,17 +350,19 @@ void QSettingsHeading::read(const QString &filename)
381 stream.setEncoding(QTextStream::UnicodeUTF8); 350 stream.setEncoding(QTextStream::UnicodeUTF8);
382 while (! stream.atEnd()) 351 while (! stream.atEnd())
383 parseLine(stream); 352 parseLine(stream);
384 353
385 git = end(); 354 git = end();
386 355
387 file.close(); 356 file.close();
388 357
358#ifndef Q_WS_WIN
389 closelock( lockfd ); 359 closelock( lockfd );
360#endif
390} 361}
391 362
392 363
393void QSettingsHeading::parseLine(QTextStream &stream) 364void QSettingsHeading::parseLine(QTextStream &stream)
394{ 365{
395 QString line = stream.readLine(); 366 QString line = stream.readLine();
396 if (line.isEmpty()) 367 if (line.isEmpty())
397 // empty line... we'll allow it 368 // empty line... we'll allow it
@@ -399,17 +370,17 @@ void QSettingsHeading::parseLine(QTextStream &stream)
399 370
400 if (line[0] == QChar('#')) 371 if (line[0] == QChar('#'))
401 // commented line 372 // commented line
402 return; 373 return;
403 374
404 if (line[0] == QChar('[')) { 375 if (line[0] == QChar('[')) {
405 QString gname = line; 376 QString gname = line;
406 377
407 gname = gname.remove(0, 1); 378 gname = gname.remove((uint)0, 1);
408 if (gname[(int)gname.length() - 1] == QChar(']')) 379 if (gname[(int)gname.length() - 1] == QChar(']'))
409 gname = gname.remove(gname.length() - 1, 1); 380 gname = gname.remove(gname.length() - 1, 1);
410 381
411 git = find(gname); 382 git = find(gname);
412 if (git == end()) 383 if (git == end())
413 git = replace(gname, QSettingsGroup()); 384 git = replace(gname, QSettingsGroup());
414 } else { 385 } else {
415 if (git == end()) { 386 if (git == end()) {
@@ -521,21 +492,17 @@ QSettingsPrivate::QSettingsPrivate( QSettings::Format format )
521 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE ); 492 SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
522 appSettings = QString::fromLocal8Bit( path ); 493 appSettings = QString::fromLocal8Bit( path );
523 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE ); 494 SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
524 defPath = QString::fromLocal8Bit( path ); 495 defPath = QString::fromLocal8Bit( path );
525 } 496 }
526 } ); 497 } );
527#endif // Q_OS_TEMP 498#endif // Q_OS_TEMP
528#else 499#else
529// for now 500 defPath = qInstallPathSysconf();
530#define QSETTINGS_DEFAULT_PATH_SUFFIX "/etc/settings"
531
532 defPath = qInstallPath();
533 defPath += QSETTINGS_DEFAULT_PATH_SUFFIX;
534#endif 501#endif
535 QDir dir(appSettings); 502 QDir dir(appSettings);
536 if (! dir.exists()) { 503 if (! dir.exists()) {
537 if (! dir.mkdir(dir.path())) 504 if (! dir.mkdir(dir.path()))
538#if defined(QT_CHECK_STATE) 505#if defined(QT_CHECK_STATE)
539 qWarning("QSettings: error creating %s", dir.path().latin1()); 506 qWarning("QSettings: error creating %s", dir.path().latin1());
540#else 507#else
541 ; 508 ;
@@ -696,37 +663,42 @@ QDateTime QSettingsPrivate::modificationTime()
696 datetime = fi.lastModified(); 663 datetime = fi.lastModified();
697 } 664 }
698 665
699 return datetime; 666 return datetime;
700} 667}
701 668
702bool qt_verify_key( const QString &key ) 669bool qt_verify_key( const QString &key )
703{ 670{
704 if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\\\r\\\\n" ) ) ) 671 if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\r\\n]" ) ) )
705 return FALSE; 672 return FALSE;
706 return TRUE; 673 return TRUE;
707} 674}
708 675
709static inline QString groupKey( const QString &group, const QString &key ) 676static QString groupKey( const QString &group, const QString &key )
710{ 677{
678 QString grp_key;
711 if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) { 679 if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) {
712 // group is empty, or it contains a single '/', so we just return the key 680 // group is empty, or it contains a single '/', so we just return the key
713 if ( key.startsWith( "/" ) ) 681 if ( key.startsWith( "/" ) )
714 return key; 682 grp_key = key;
715 return "/" + key; 683 else
684 grp_key = "/" + key;
716 } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) { 685 } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) {
717 return group + key; 686 grp_key = group + key;
687 } else {
688 grp_key = group + "/" + key;
718 } 689 }
719 return group + "/" + key; 690 return grp_key;
720} 691}
721 692
722/*! 693/*!
723 Inserts \a path into the settings search path. The semantics of \a 694 Inserts \a path into the settings search path. The semantics of \a
724 path depends on the system \a s. 695 path depends on the system \a s. It is usually easier and better to
696 use setPath() instead of this function.
725 697
726 When \a s is \e Windows and the execution environment is \e not 698 When \a s is \e Windows and the execution environment is \e not
727 Windows the function does nothing. Similarly when \a s is \e Unix and 699 Windows the function does nothing. Similarly when \a s is \e Unix and
728 the execution environment is \e not Unix the function does nothing. 700 the execution environment is \e not Unix the function does nothing.
729 701
730 When \a s is \e Windows, and the execution environment is Windows, the 702 When \a s is \e Windows, and the execution environment is Windows, the
731 search path list will be used as the first subfolder of the "Software" 703 search path list will be used as the first subfolder of the "Software"
732 folder in the registry. 704 folder in the registry.
@@ -761,41 +733,45 @@ static inline QString groupKey( const QString &group, const QString &key )
761 HKEY_LOCAL_MACHINE space. 733 HKEY_LOCAL_MACHINE space.
762 734
763 When \a s is \e Unix, and the execution environment is Unix, the 735 When \a s is \e Unix, and the execution environment is Unix, the
764 search path list will be used when trying to determine a suitable 736 search path list will be used when trying to determine a suitable
765 filename for reading and writing settings files. By default, there are 737 filename for reading and writing settings files. By default, there are
766 two entries in the search path: 738 two entries in the search path:
767 739
768 \list 1 740 \list 1
769 \i INSTALL/etc - where \c INSTALL is the directory where Qt was installed. 741 \i \c SYSCONF - where \c SYSCONF is a directory specified when
770 \i $HOME/.qt/ - where \c $HOME is the user's home directory. 742 configuring Qt; by default it is INSTALL/etc/settings.
743 \i \c $HOME/.qt/ - where \c $HOME is the user's home directory.
771 \endlist 744 \endlist
772 745
773 All insertions into the search path will go before $HOME/.qt/. 746 All insertions into the search path will go before $HOME/.qt/.
774 For example: 747 For example:
775 \code 748 \code
776 QSettings settings; 749 QSettings settings;
777 settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/etc" ); 750 settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/etc" );
778 settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/MyApplication/etc" ); 751 settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/MyApplication/etc" );
779 // ... 752 // ...
780 \endcode 753 \endcode
781 Will result in a search path of: 754 Will result in a search path of:
782 \list 1 755 \list 1
783 \i INSTALL/etc 756 \i SYSCONF
784 \i /opt/MyCompany/share/etc 757 \i /opt/MyCompany/share/etc
785 \i /opt/MyCompany/share/MyApplication/etc 758 \i /opt/MyCompany/share/MyApplication/etc
786 \i $HOME/.qt 759 \i $HOME/.qt
787 \endlist 760 \endlist
788 When reading settings the files are searched in the order shown 761 When reading settings the files are searched in the order shown
789 above, with later settings overriding earlier settings. Files for 762 above, with later settings overriding earlier settings. Files for
790 which the user doesn't have read permission are ignored. When saving 763 which the user doesn't have read permission are ignored. When saving
791 settings QSettings works in the order shown above, writing 764 settings QSettings works in the order shown above, writing
792 to the first settings file for which the user has write permission. 765 to the first settings file for which the user has write permission.
793 766
767 Note that paths in the file system are not created by this
768 function, so they must already exist to be useful.
769
794 Settings under Unix are stored in files whose names are based on the 770 Settings under Unix are stored in files whose names are based on the
795 first subkey of the key (not including the search path). The algorithm 771 first subkey of the key (not including the search path). The algorithm
796 for creating names is essentially: lowercase the first subkey, replace 772 for creating names is essentially: lowercase the first subkey, replace
797 spaces with underscores and add 'rc', e.g. 773 spaces with underscores and add 'rc', e.g.
798 <tt>/MyCompany/MyApplication/background color</tt> will be stored in 774 <tt>/MyCompany/MyApplication/background color</tt> will be stored in
799 <tt>myapplicationrc</tt> (assuming that <tt>/MyCompany</tt> is part of 775 <tt>myapplicationrc</tt> (assuming that <tt>/MyCompany</tt> is part of
800 the search path). 776 the search path).
801 777
@@ -810,17 +786,17 @@ void QSettings::insertSearchPath( System s, const QString &path)
810 return; 786 return;
811 } 787 }
812#endif 788#endif
813 789
814#if !defined(Q_WS_WIN) 790#if !defined(Q_WS_WIN)
815 if ( s == Windows ) 791 if ( s == Windows )
816 return; 792 return;
817#endif 793#endif
818#if !defined(Q_WS_WIN) 794#if !defined(Q_OS_MAC)
819 if ( s == Mac ) 795 if ( s == Mac )
820 return; 796 return;
821#endif 797#endif
822 798
823 if ( !qt_verify_key( path ) ) { 799 if ( !qt_verify_key( path ) ) {
824#if defined(QT_CHECK_STATE) 800#if defined(QT_CHECK_STATE)
825 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); 801 qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
826#endif 802#endif
@@ -959,47 +935,61 @@ bool QSettings::sync()
959 935
960 bool success = TRUE; 936 bool success = TRUE;
961 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin(); 937 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin();
962 938
963 while (it != d->headings.end()) { 939 while (it != d->headings.end()) {
964 // determine filename 940 // determine filename
965 QSettingsHeading hd(*it); 941 QSettingsHeading hd(*it);
966 QSettingsHeading::Iterator hdit = hd.begin(); 942 QSettingsHeading::Iterator hdit = hd.begin();
967 QFile file; 943 QString filename;
968 944
969 QStringList::Iterator pit = d->searchPaths.begin(); 945 QStringList::Iterator pit = d->searchPaths.begin();
970 if ( !d->globalScope ) 946 if ( !d->globalScope )
971 ++pit; 947 ++pit;
972 while (pit != d->searchPaths.end()) { 948 while (pit != d->searchPaths.end()) {
973 QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_"); 949 QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_");
974 QFileInfo di(*pit); 950 QFileInfo di(*pit);
951 if ( !di.exists() ) {
952 QDir dir;
953 dir.mkdir( *pit );
954 }
955
975 QFileInfo fi((*pit++) + "/" + filebase + "rc"); 956 QFileInfo fi((*pit++) + "/" + filebase + "rc");
976 957
977 if ((fi.exists() && fi.isFile() && fi.isWritable()) || 958 if ((fi.exists() && fi.isFile() && fi.isWritable()) ||
978 (! fi.exists() && di.isDir() && di.isWritable())) { 959 (! fi.exists() && di.isDir()
979 file.setName(fi.filePath()); 960#ifndef Q_WS_WIN
961 && di.isWritable()
962#else
963 && ((qWinVersion()&Qt::WV_NT_based) > Qt::WV_2000 || di.isWritable())
964#endif
965 )) {
966 filename = fi.filePath();
980 break; 967 break;
981 } 968 }
982 } 969 }
983 970
984 ++it; 971 ++it;
985 972
986 if ( file.name().isEmpty() ) { 973 if ( filename.isEmpty() ) {
987 974
988#ifdef QT_CHECK_STATE 975#ifdef QT_CHECK_STATE
989 qWarning("QSettings::sync: filename is null/empty"); 976 qWarning("QSettings::sync: filename is null/empty");
990#endif // QT_CHECK_STATE 977#endif // QT_CHECK_STATE
991 978
992 success = FALSE; 979 success = FALSE;
993 continue; 980 continue;
994 } 981 }
995 982
996 HANDLE lockfd = openlock( file.name(), Q_LOCKWRITE ); 983#ifndef Q_WS_WIN
984 HANDLE lockfd = openlock( filename, Q_LOCKWRITE );
985#endif
997 986
987 QFile file( filename + ".tmp" );
998 if (! file.open(IO_WriteOnly)) { 988 if (! file.open(IO_WriteOnly)) {
999 989
1000#ifdef QT_CHECK_STATE 990#ifdef QT_CHECK_STATE
1001 qWarning("QSettings::sync: failed to open '%s' for writing", 991 qWarning("QSettings::sync: failed to open '%s' for writing",
1002 file.name().latin1()); 992 file.name().latin1());
1003#endif // QT_CHECK_STATE 993#endif // QT_CHECK_STATE
1004 994
1005 success = FALSE; 995 success = FALSE;
@@ -1042,17 +1032,36 @@ bool QSettings::sync()
1042 qWarning("QSettings::sync: error at end of write"); 1032 qWarning("QSettings::sync: error at end of write");
1043#endif // QT_CHECK_STATE 1033#endif // QT_CHECK_STATE
1044 1034
1045 success = FALSE; 1035 success = FALSE;
1046 } 1036 }
1047 1037
1048 file.close(); 1038 file.close();
1049 1039
1040 if ( success ) {
1041 QDir dir( QFileInfo( file ).dir( TRUE ) );
1042 if ( dir.exists( filename ) && !dir.remove( filename ) ||
1043 !dir.rename( file.name(), filename, TRUE ) ) {
1044
1045#ifdef QT_CHECK_STATE
1046 qWarning( "QSettings::sync: error writing file '%s'",
1047 QFile::encodeName( filename ).data() );
1048#endif // QT_CHECK_STATE
1049
1050 success = FALSE;
1051 }
1052 }
1053
1054 // remove temporary file
1055 file.remove();
1056
1057#ifndef Q_WS_WIN
1050 closelock( lockfd ); 1058 closelock( lockfd );
1059#endif
1051 } 1060 }
1052 1061
1053 d->modified = FALSE; 1062 d->modified = FALSE;
1054 1063
1055 return success; 1064 return success;
1056} 1065}
1057 1066
1058 1067
@@ -1067,29 +1076,30 @@ bool QSettings::sync()
1067 \sa readEntry(), readNumEntry(), readDoubleEntry(), writeEntry(), removeEntry() 1076 \sa readEntry(), readNumEntry(), readDoubleEntry(), writeEntry(), removeEntry()
1068*/ 1077*/
1069 1078
1070/*! 1079/*!
1071 \internal 1080 \internal
1072*/ 1081*/
1073bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) 1082bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok )
1074{ 1083{
1075 if ( !qt_verify_key( key ) ) { 1084 QString grp_key( groupKey( group(), key ) );
1085 if ( !qt_verify_key( grp_key ) ) {
1076#if defined(QT_CHECK_STATE) 1086#if defined(QT_CHECK_STATE)
1077 qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1087 qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1078#endif 1088#endif
1079 if ( ok ) 1089 if ( ok )
1080 *ok = FALSE; 1090 *ok = FALSE;
1081 1091
1082 return def; 1092 return def;
1083 } 1093 }
1084 1094
1085#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1095#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1086 if ( d->sysd ) 1096 if ( d->sysd )
1087 return d->sysReadBoolEntry( groupKey( group(), key ), def, ok ); 1097 return d->sysReadBoolEntry( grp_key, def, ok );
1088#endif 1098#endif
1089 1099
1090 QString value = readEntry( key, ( def ? "true" : "false" ), ok ); 1100 QString value = readEntry( key, ( def ? "true" : "false" ), ok );
1091 1101
1092 if (value.lower() == "true") 1102 if (value.lower() == "true")
1093 return TRUE; 1103 return TRUE;
1094 else if (value.lower() == "false") 1104 else if (value.lower() == "false")
1095 return FALSE; 1105 return FALSE;
@@ -1118,29 +1128,30 @@ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok )
1118 \sa readEntry(), readNumEntry(), readBoolEntry(), writeEntry(), removeEntry() 1128 \sa readEntry(), readNumEntry(), readBoolEntry(), writeEntry(), removeEntry()
1119*/ 1129*/
1120 1130
1121/*! 1131/*!
1122 \internal 1132 \internal
1123*/ 1133*/
1124double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) 1134double QSettings::readDoubleEntry(const QString &key, double def, bool *ok )
1125{ 1135{
1126 if ( !qt_verify_key( key ) ) { 1136 QString grp_key( groupKey( group(), key ) );
1137 if ( !qt_verify_key( grp_key ) ) {
1127#if defined(QT_CHECK_STATE) 1138#if defined(QT_CHECK_STATE)
1128 qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1139 qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1129#endif 1140#endif
1130 if ( ok ) 1141 if ( ok )
1131 *ok = FALSE; 1142 *ok = FALSE;
1132 1143
1133 return def; 1144 return def;
1134 } 1145 }
1135 1146
1136#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1147#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1137 if ( d->sysd ) 1148 if ( d->sysd )
1138 return d->sysReadDoubleEntry( groupKey( group(), key ), def, ok ); 1149 return d->sysReadDoubleEntry( grp_key, def, ok );
1139#endif 1150#endif
1140 1151
1141 QString value = readEntry( key, QString::number(def), ok ); 1152 QString value = readEntry( key, QString::number(def), ok );
1142 bool conv_ok; 1153 bool conv_ok;
1143 double retval = value.toDouble( &conv_ok ); 1154 double retval = value.toDouble( &conv_ok );
1144 if ( conv_ok ) 1155 if ( conv_ok )
1145 return retval; 1156 return retval;
1146 if ( ! value.isEmpty() ) 1157 if ( ! value.isEmpty() )
@@ -1163,28 +1174,29 @@ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok )
1163 \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry() 1174 \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry()
1164*/ 1175*/
1165 1176
1166/*! 1177/*!
1167 \internal 1178 \internal
1168*/ 1179*/
1169int QSettings::readNumEntry(const QString &key, int def, bool *ok ) 1180int QSettings::readNumEntry(const QString &key, int def, bool *ok )
1170{ 1181{
1171 if ( !qt_verify_key( key ) ) { 1182 QString grp_key( groupKey( group(), key ) );
1183 if ( !qt_verify_key( grp_key ) ) {
1172#if defined(QT_CHECK_STATE) 1184#if defined(QT_CHECK_STATE)
1173 qWarning( "QSettings::readNumEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1185 qWarning( "QSettings::readNumEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1174#endif 1186#endif
1175 if ( ok ) 1187 if ( ok )
1176 *ok = FALSE; 1188 *ok = FALSE;
1177 return def; 1189 return def;
1178 } 1190 }
1179 1191
1180#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1192#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1181 if ( d->sysd ) 1193 if ( d->sysd )
1182 return d->sysReadNumEntry( groupKey( group(), key ), def, ok ); 1194 return d->sysReadNumEntry( grp_key, def, ok );
1183#endif 1195#endif
1184 1196
1185 QString value = readEntry( key, QString::number( def ), ok ); 1197 QString value = readEntry( key, QString::number( def ), ok );
1186 bool conv_ok; 1198 bool conv_ok;
1187 int retval = value.toInt( &conv_ok ); 1199 int retval = value.toInt( &conv_ok );
1188 if ( conv_ok ) 1200 if ( conv_ok )
1189 return retval; 1201 return retval;
1190 if ( ! value.isEmpty() ) 1202 if ( ! value.isEmpty() )
@@ -1207,45 +1219,44 @@ int QSettings::readNumEntry(const QString &key, int def, bool *ok )
1207 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry() 1219 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry()
1208*/ 1220*/
1209 1221
1210/*! 1222/*!
1211 \internal 1223 \internal
1212*/ 1224*/
1213QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) 1225QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1214{ 1226{
1215 if ( !qt_verify_key( key ) ) { 1227 QString grp_key( groupKey( group(), key ) );
1228 if ( !qt_verify_key( grp_key ) ) {
1216#if defined(QT_CHECK_STATE) 1229#if defined(QT_CHECK_STATE)
1217 qWarning( "QSettings::readEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1230 qWarning( "QSettings::readEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1218#endif 1231#endif
1219 if ( ok ) 1232 if ( ok )
1220 *ok = FALSE; 1233 *ok = FALSE;
1221 1234
1222 return def; 1235 return def;
1223 } 1236 }
1224 1237
1225 QString theKey = groupKey( group(), key );
1226
1227#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1238#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1228 if ( d->sysd ) 1239 if ( d->sysd )
1229 return d->sysReadEntry( theKey, def, ok ); 1240 return d->sysReadEntry( grp_key, def, ok );
1230#endif 1241#endif
1231 1242
1232 if ( ok ) // no, everything is not ok 1243 if ( ok ) // no, everything is not ok
1233 *ok = FALSE; 1244 *ok = FALSE;
1234 1245
1235 QString realkey; 1246 QString realkey;
1236 1247
1237 if (theKey[0] == '/') { 1248 if (grp_key[0] == '/') {
1238 // parse our key 1249 // parse our key
1239 QStringList list(QStringList::split('/', theKey)); 1250 QStringList list(QStringList::split('/', grp_key));
1240 1251
1241 if (list.count() < 2) { 1252 if (list.count() < 2) {
1242#ifdef QT_CHECK_STATE 1253#ifdef QT_CHECK_STATE
1243 qWarning("QSettings::readEntry: invalid key '%s'", theKey.latin1()); 1254 qWarning("QSettings::readEntry: invalid key '%s'", grp_key.latin1());
1244#endif // QT_CHECK_STATE 1255#endif // QT_CHECK_STATE
1245 if ( ok ) 1256 if ( ok )
1246 *ok = FALSE; 1257 *ok = FALSE;
1247 return def; 1258 return def;
1248 } 1259 }
1249 1260
1250 if (list.count() == 2) { 1261 if (list.count() == 2) {
1251 d->heading = list[0]; 1262 d->heading = list[0];
@@ -1257,18 +1268,19 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1257 1268
1258 // remove the group from the list 1269 // remove the group from the list
1259 list.remove(list.at(1)); 1270 list.remove(list.at(1));
1260 // remove the heading from the list 1271 // remove the heading from the list
1261 list.remove(list.at(0)); 1272 list.remove(list.at(0));
1262 1273
1263 realkey = list.join("/"); 1274 realkey = list.join("/");
1264 } 1275 }
1265 } else 1276 } else {
1266 realkey = theKey; 1277 realkey = grp_key;
1278 }
1267 1279
1268 QSettingsGroup grp = d->readGroup(); 1280 QSettingsGroup grp = d->readGroup();
1269 QSettingsGroup::const_iterator it = grp.find( realkey ), end = grp.end(); 1281 QSettingsGroup::const_iterator it = grp.find( realkey ), end = grp.end();
1270 QString retval = def; 1282 QString retval = def;
1271 if ( it != end ) { 1283 if ( it != end ) {
1272 // found the value we needed 1284 // found the value we needed
1273 retval = *it; 1285 retval = *it;
1274 if ( ok ) *ok = TRUE; 1286 if ( ok ) *ok = TRUE;
@@ -1285,26 +1297,27 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok )
1285 1297
1286 If an error occurs the settings are left unchanged and FALSE is 1298 If an error occurs the settings are left unchanged and FALSE is
1287 returned; otherwise TRUE is returned. 1299 returned; otherwise TRUE is returned.
1288 1300
1289 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1301 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1290*/ 1302*/
1291bool QSettings::writeEntry(const QString &key, bool value) 1303bool QSettings::writeEntry(const QString &key, bool value)
1292{ 1304{
1293 if ( !qt_verify_key( key ) ) { 1305 QString grp_key( groupKey( group(), key ) );
1306 if ( !qt_verify_key( grp_key ) ) {
1294#if defined(QT_CHECK_STATE) 1307#if defined(QT_CHECK_STATE)
1295 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1308 qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1296#endif 1309#endif
1297 return FALSE; 1310 return FALSE;
1298 } 1311 }
1299 1312
1300#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1313#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1301 if ( d->sysd ) 1314 if ( d->sysd )
1302 return d->sysWriteEntry( groupKey( group(), key ), value ); 1315 return d->sysWriteEntry( grp_key, value );
1303#endif 1316#endif
1304 QString s(value ? "true" : "false"); 1317 QString s(value ? "true" : "false");
1305 return writeEntry(key, s); 1318 return writeEntry(key, s);
1306} 1319}
1307#endif 1320#endif
1308 1321
1309 1322
1310/*! 1323/*!
@@ -1315,26 +1328,27 @@ bool QSettings::writeEntry(const QString &key, bool value)
1315 1328
1316 If an error occurs the settings are left unchanged and FALSE is 1329 If an error occurs the settings are left unchanged and FALSE is
1317 returned; otherwise TRUE is returned. 1330 returned; otherwise TRUE is returned.
1318 1331
1319 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1332 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1320*/ 1333*/
1321bool QSettings::writeEntry(const QString &key, double value) 1334bool QSettings::writeEntry(const QString &key, double value)
1322{ 1335{
1323 if ( !qt_verify_key( key ) ) { 1336 QString grp_key( groupKey( group(), key ) );
1337 if ( !qt_verify_key( grp_key ) ) {
1324#if defined(QT_CHECK_STATE) 1338#if defined(QT_CHECK_STATE)
1325 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1339 qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1326#endif 1340#endif
1327 return FALSE; 1341 return FALSE;
1328 } 1342 }
1329 1343
1330#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1344#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1331 if ( d->sysd ) 1345 if ( d->sysd )
1332 return d->sysWriteEntry( groupKey( group(), key ), value ); 1346 return d->sysWriteEntry( grp_key, value );
1333#endif 1347#endif
1334 QString s(QString::number(value)); 1348 QString s(QString::number(value));
1335 return writeEntry(key, s); 1349 return writeEntry(key, s);
1336} 1350}
1337 1351
1338 1352
1339/*! 1353/*!
1340 \overload 1354 \overload
@@ -1344,26 +1358,27 @@ bool QSettings::writeEntry(const QString &key, double value)
1344 1358
1345 If an error occurs the settings are left unchanged and FALSE is 1359 If an error occurs the settings are left unchanged and FALSE is
1346 returned; otherwise TRUE is returned. 1360 returned; otherwise TRUE is returned.
1347 1361
1348 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1362 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1349*/ 1363*/
1350bool QSettings::writeEntry(const QString &key, int value) 1364bool QSettings::writeEntry(const QString &key, int value)
1351{ 1365{
1352 if ( !qt_verify_key( key ) ) { 1366 QString grp_key( groupKey( group(), key ) );
1367 if ( !qt_verify_key( grp_key ) ) {
1353#if defined(QT_CHECK_STATE) 1368#if defined(QT_CHECK_STATE)
1354 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1369 qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1355#endif 1370#endif
1356 return FALSE; 1371 return FALSE;
1357 } 1372 }
1358 1373
1359#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1374#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1360 if ( d->sysd ) 1375 if ( d->sysd )
1361 return d->sysWriteEntry( groupKey( group(), key ), value ); 1376 return d->sysWriteEntry( grp_key, value );
1362#endif 1377#endif
1363 QString s(QString::number(value)); 1378 QString s(QString::number(value));
1364 return writeEntry(key, s); 1379 return writeEntry(key, s);
1365} 1380}
1366 1381
1367 1382
1368/*! 1383/*!
1369 \internal 1384 \internal
@@ -1378,23 +1393,16 @@ bool QSettings::writeEntry(const QString &key, int value)
1378 1393
1379 If an error occurs, this functions returns FALSE and the object is left 1394 If an error occurs, this functions returns FALSE and the object is left
1380 unchanged. 1395 unchanged.
1381 1396
1382 \sa readEntry(), removeEntry() 1397 \sa readEntry(), removeEntry()
1383*/ 1398*/
1384bool QSettings::writeEntry(const QString &key, const char *value) 1399bool QSettings::writeEntry(const QString &key, const char *value)
1385{ 1400{
1386 if ( !qt_verify_key( key ) ) {
1387#if defined(QT_CHECK_STATE)
1388 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() );
1389#endif
1390 return FALSE;
1391 }
1392
1393 return writeEntry(key, QString(value)); 1401 return writeEntry(key, QString(value));
1394} 1402}
1395 1403
1396 1404
1397/*! 1405/*!
1398 \overload 1406 \overload
1399 Writes the string entry \a value into key \a key. The \a key is 1407 Writes the string entry \a value into key \a key. The \a key is
1400 created if it doesn't exist. Any previous value is overwritten by \a 1408 created if it doesn't exist. Any previous value is overwritten by \a
@@ -1403,40 +1411,39 @@ bool QSettings::writeEntry(const QString &key, const char *value)
1403 1411
1404 If an error occurs the settings are left unchanged and FALSE is 1412 If an error occurs the settings are left unchanged and FALSE is
1405 returned; otherwise TRUE is returned. 1413 returned; otherwise TRUE is returned.
1406 1414
1407 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1415 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
1408*/ 1416*/
1409bool QSettings::writeEntry(const QString &key, const QString &value) 1417bool QSettings::writeEntry(const QString &key, const QString &value)
1410{ 1418{
1411 if ( !qt_verify_key( key ) ) { 1419 QString grp_key( groupKey( group(), key ) );
1420 if ( !qt_verify_key( grp_key ) ) {
1412#if defined(QT_CHECK_STATE) 1421#if defined(QT_CHECK_STATE)
1413 qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1422 qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1414#endif 1423#endif
1415 return FALSE; 1424 return FALSE;
1416 } 1425 }
1417 1426
1418 QString theKey = groupKey( group(), key );
1419
1420#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1427#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1421 if ( d->sysd ) 1428 if ( d->sysd )
1422 return d->sysWriteEntry( theKey, value ); 1429 return d->sysWriteEntry( grp_key, value );
1423#endif 1430#endif
1424 // NOTE: we *do* allow value to be a null/empty string 1431 // NOTE: we *do* allow value to be a null/empty string
1425 1432
1426 QString realkey; 1433 QString realkey;
1427 1434
1428 if (theKey[0] == '/') { 1435 if (grp_key[0] == '/') {
1429 // parse our key 1436 // parse our key
1430 QStringList list(QStringList::split('/', theKey)); 1437 QStringList list(QStringList::split('/', grp_key));
1431 1438
1432 if (list.count() < 2) { 1439 if (list.count() < 2) {
1433#ifdef QT_CHECK_STATE 1440#ifdef QT_CHECK_STATE
1434 qWarning("QSettings::writeEntry: invalid key '%s'", theKey.latin1()); 1441 qWarning("QSettings::writeEntry: invalid key '%s'", grp_key.latin1());
1435#endif // QT_CHECK_STATE 1442#endif // QT_CHECK_STATE
1436 1443
1437 return FALSE; 1444 return FALSE;
1438 } 1445 }
1439 1446
1440 if (list.count() == 2) { 1447 if (list.count() == 2) {
1441 d->heading = list[0]; 1448 d->heading = list[0];
1442 d->group = "General"; 1449 d->group = "General";
@@ -1447,56 +1454,55 @@ bool QSettings::writeEntry(const QString &key, const QString &value)
1447 1454
1448 // remove the group from the list 1455 // remove the group from the list
1449 list.remove(list.at(1)); 1456 list.remove(list.at(1));
1450 // remove the heading from the list 1457 // remove the heading from the list
1451 list.remove(list.at(0)); 1458 list.remove(list.at(0));
1452 1459
1453 realkey = list.join("/"); 1460 realkey = list.join("/");
1454 } 1461 }
1455 } else 1462 } else {
1456 realkey = theKey; 1463 realkey = grp_key;
1464 }
1457 1465
1458 d->writeGroup(realkey, value); 1466 d->writeGroup(realkey, value);
1459 return TRUE; 1467 return TRUE;
1460} 1468}
1461 1469
1462 1470
1463/*! 1471/*!
1464 Removes the entry specified by \a key. 1472 Removes the entry specified by \a key.
1465 1473
1466 Returns TRUE if the entry existed and was removed; otherwise returns FALSE. 1474 Returns TRUE if the entry existed and was removed; otherwise returns FALSE.
1467 1475
1468 \sa readEntry(), writeEntry() 1476 \sa readEntry(), writeEntry()
1469*/ 1477*/
1470bool QSettings::removeEntry(const QString &key) 1478bool QSettings::removeEntry(const QString &key)
1471{ 1479{
1472 if ( !qt_verify_key( key ) ) { 1480 QString grp_key( groupKey( group(), key ) );
1481 if ( !qt_verify_key( grp_key ) ) {
1473#if defined(QT_CHECK_STATE) 1482#if defined(QT_CHECK_STATE)
1474 qWarning( "QSettings::removeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1483 qWarning( "QSettings::removeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1475#endif 1484#endif
1476 return FALSE; 1485 return FALSE;
1477 } 1486 }
1478 1487
1479 QString theKey = groupKey( group(), key );
1480
1481#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1488#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1482 if ( d->sysd ) 1489 if ( d->sysd )
1483 return d->sysRemoveEntry( theKey ); 1490 return d->sysRemoveEntry( grp_key );
1484#endif 1491#endif
1485 1492
1486 QString realkey; 1493 QString realkey;
1487 1494 if (grp_key[0] == '/') {
1488 if (theKey[0] == '/') {
1489 // parse our key 1495 // parse our key
1490 QStringList list(QStringList::split('/', theKey)); 1496 QStringList list(QStringList::split('/', grp_key));
1491 1497
1492 if (list.count() < 2) { 1498 if (list.count() < 2) {
1493#ifdef QT_CHECK_STATE 1499#ifdef QT_CHECK_STATE
1494 qWarning("QSettings::removeEntry: invalid key '%s'", theKey.latin1()); 1500 qWarning("QSettings::removeEntry: invalid key '%s'", grp_key.latin1());
1495#endif // QT_CHECK_STATE 1501#endif // QT_CHECK_STATE
1496 1502
1497 return FALSE; 1503 return FALSE;
1498 } 1504 }
1499 1505
1500 if (list.count() == 2) { 1506 if (list.count() == 2) {
1501 d->heading = list[0]; 1507 d->heading = list[0];
1502 d->group = "General"; 1508 d->group = "General";
@@ -1507,18 +1513,19 @@ bool QSettings::removeEntry(const QString &key)
1507 1513
1508 // remove the group from the list 1514 // remove the group from the list
1509 list.remove(list.at(1)); 1515 list.remove(list.at(1));
1510 // remove the heading from the list 1516 // remove the heading from the list
1511 list.remove(list.at(0)); 1517 list.remove(list.at(0));
1512 1518
1513 realkey = list.join("/"); 1519 realkey = list.join("/");
1514 } 1520 }
1515 } else 1521 } else {
1516 realkey = theKey; 1522 realkey = grp_key;
1523 }
1517 1524
1518 d->removeGroup(realkey); 1525 d->removeGroup(realkey);
1519 return TRUE; 1526 return TRUE;
1520} 1527}
1521 1528
1522 1529
1523/*! 1530/*!
1524 Returns a list of the keys which contain entries under \a key. Does \e 1531 Returns a list of the keys which contain entries under \a key. Does \e
@@ -1543,38 +1550,37 @@ bool QSettings::removeEntry(const QString &key)
1543 the keys and then read each entry, or simply read each entry 1550 the keys and then read each entry, or simply read each entry
1544 directly by specifying its full key, e.g. 1551 directly by specifying its full key, e.g.
1545 "/MyCompany/MyApplication/geometry/y". 1552 "/MyCompany/MyApplication/geometry/y".
1546 1553
1547 \sa subkeyList() 1554 \sa subkeyList()
1548*/ 1555*/
1549QStringList QSettings::entryList(const QString &key) const 1556QStringList QSettings::entryList(const QString &key) const
1550{ 1557{
1551 if ( !qt_verify_key( key ) ) { 1558 QString grp_key( groupKey( group(), key ) );
1559 if ( !qt_verify_key( grp_key ) ) {
1552#if defined(QT_CHECK_STATE) 1560#if defined(QT_CHECK_STATE)
1553 qWarning( "QSettings::entryList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); 1561 qWarning( "QSettings::entryList: Invalid key: %s", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1554#endif 1562#endif
1555 return QStringList(); 1563 return QStringList();
1556 } 1564 }
1557 1565
1558 QString theKey = groupKey( group(), key );
1559
1560#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1566#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1561 if ( d->sysd ) 1567 if ( d->sysd )
1562 return d->sysEntryList( theKey ); 1568 return d->sysEntryList( grp_key );
1563#endif 1569#endif
1564 1570
1565 QString realkey; 1571 QString realkey;
1566 if (theKey[0] == '/') { 1572 if (grp_key[0] == '/') {
1567 // parse our key 1573 // parse our key
1568 QStringList list(QStringList::split('/', theKey)); 1574 QStringList list(QStringList::split('/', grp_key));
1569 1575
1570 if (list.count() < 1) { 1576 if (list.count() < 1) {
1571#ifdef QT_CHECK_STATE 1577#ifdef QT_CHECK_STATE
1572 qWarning("QSettings::listEntries: invalid key '%s'", theKey.latin1()); 1578 qWarning("QSettings::listEntries: invalid key '%s'", grp_key.latin1());
1573#endif // QT_CHECK_STATE 1579#endif // QT_CHECK_STATE
1574 1580
1575 return QStringList(); 1581 return QStringList();
1576 } 1582 }
1577 1583
1578 if (list.count() == 1) { 1584 if (list.count() == 1) {
1579 d->heading = list[0]; 1585 d->heading = list[0];
1580 d->group = "General"; 1586 d->group = "General";
@@ -1585,17 +1591,17 @@ QStringList QSettings::entryList(const QString &key) const
1585 // remove the group from the list 1591 // remove the group from the list
1586 list.remove(list.at(1)); 1592 list.remove(list.at(1));
1587 // remove the heading from the list 1593 // remove the heading from the list
1588 list.remove(list.at(0)); 1594 list.remove(list.at(0));
1589 1595
1590 realkey = list.join("/"); 1596 realkey = list.join("/");
1591 } 1597 }
1592 } else 1598 } else
1593 realkey = theKey; 1599 realkey = grp_key;
1594 1600
1595 QSettingsGroup grp = d->readGroup(); 1601 QSettingsGroup grp = d->readGroup();
1596 QSettingsGroup::Iterator it = grp.begin(); 1602 QSettingsGroup::Iterator it = grp.begin();
1597 QStringList ret; 1603 QStringList ret;
1598 QString itkey; 1604 QString itkey;
1599 while (it != grp.end()) { 1605 while (it != grp.end()) {
1600 itkey = it.key(); 1606 itkey = it.key();
1601 ++it; 1607 ++it;
@@ -1640,39 +1646,38 @@ QStringList QSettings::entryList(const QString &key) const
1640 'background color' or 'foreground color' because they are keys which 1646 'background color' or 'foreground color' because they are keys which
1641 contain entries not keys. To get a list of keys that have values 1647 contain entries not keys. To get a list of keys that have values
1642 rather than subkeys use entryList(). 1648 rather than subkeys use entryList().
1643 1649
1644 \sa entryList() 1650 \sa entryList()
1645*/ 1651*/
1646QStringList QSettings::subkeyList(const QString &key) const 1652QStringList QSettings::subkeyList(const QString &key) const
1647{ 1653{
1648 if ( !qt_verify_key( key ) ) { 1654 QString grp_key( groupKey( group(), key ) );
1655 if ( !qt_verify_key( grp_key ) ) {
1649#if defined(QT_CHECK_STATE) 1656#if defined(QT_CHECK_STATE)
1650 qWarning( "QSettings::subkeyList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); 1657 qWarning( "QSettings::subkeyList: Invalid key: %s", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1651#endif 1658#endif
1652 return QStringList(); 1659 return QStringList();
1653 } 1660 }
1654 1661
1655 QString theKey = groupKey( group(), key );
1656
1657#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1662#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1658 if ( d->sysd ) 1663 if ( d->sysd )
1659 return d->sysSubkeyList( theKey ); 1664 return d->sysSubkeyList( grp_key );
1660#endif 1665#endif
1661 1666
1662 QString realkey; 1667 QString realkey;
1663 int subkeycount = 2; 1668 int subkeycount = 2;
1664 if (theKey[0] == '/') { 1669 if (grp_key[0] == '/') {
1665 // parse our key 1670 // parse our key
1666 QStringList list(QStringList::split('/', theKey)); 1671 QStringList list(QStringList::split('/', grp_key));
1667 1672
1668 if (list.count() < 1) { 1673 if (list.count() < 1) {
1669#ifdef QT_CHECK_STATE 1674#ifdef QT_CHECK_STATE
1670 qWarning("QSettings::subkeyList: invalid key '%s'", theKey.latin1()); 1675 qWarning("QSettings::subkeyList: invalid key '%s'", grp_key.latin1());
1671#endif // QT_CHECK_STATE 1676#endif // QT_CHECK_STATE
1672 1677
1673 return QStringList(); 1678 return QStringList();
1674 } 1679 }
1675 1680
1676 subkeycount = list.count(); 1681 subkeycount = list.count();
1677 1682
1678 if (list.count() == 1) { 1683 if (list.count() == 1) {
@@ -1686,17 +1691,17 @@ QStringList QSettings::subkeyList(const QString &key) const
1686 list.remove(list.at(1)); 1691 list.remove(list.at(1));
1687 // remove the heading from the list 1692 // remove the heading from the list
1688 list.remove(list.at(0)); 1693 list.remove(list.at(0));
1689 1694
1690 realkey = list.join("/"); 1695 realkey = list.join("/");
1691 } 1696 }
1692 1697
1693 } else 1698 } else
1694 realkey = theKey; 1699 realkey = grp_key;
1695 1700
1696 QStringList ret; 1701 QStringList ret;
1697 if ( subkeycount == 1 ) { 1702 if ( subkeycount == 1 ) {
1698 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin(); 1703 QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin();
1699 while ( it != d->headings.end() ) { 1704 while ( it != d->headings.end() ) {
1700 if ( it.key() != "General" && ! ret.contains( it.key() ) ) 1705 if ( it.key() != "General" && ! ret.contains( it.key() ) )
1701 ret << it.key(); 1706 ret << it.key();
1702 ++it; 1707 ++it;
@@ -1732,39 +1737,38 @@ QStringList QSettings::subkeyList(const QString &key) const
1732} 1737}
1733 1738
1734 1739
1735/*! 1740/*!
1736 \internal 1741 \internal
1737 1742
1738 This function returns the time of last modification for \a key. 1743 This function returns the time of last modification for \a key.
1739*/ 1744*/
1740QDateTime QSettings::lastModficationTime(const QString &key) 1745QDateTime QSettings::lastModificationTime( const QString &key )
1741{ 1746{
1742 if ( !qt_verify_key( key ) ) { 1747 QString grp_key( groupKey( group(), key ) );
1748 if ( !qt_verify_key( grp_key ) ) {
1743#if defined(QT_CHECK_STATE) 1749#if defined(QT_CHECK_STATE)
1744 qWarning( "QSettings::lastModficationTime: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); 1750 qWarning( "QSettings::lastModificationTime: Invalid key '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
1745#endif 1751#endif
1746 return QDateTime(); 1752 return QDateTime();
1747 } 1753 }
1748 1754
1749 QString theKey = groupKey( group(), key );
1750
1751#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) 1755#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC))
1752 if ( d->sysd ) 1756 if ( d->sysd )
1753 return QDateTime(); 1757 return QDateTime();
1754#endif 1758#endif
1755 1759
1756 if (theKey[0] == '/') { 1760 if (grp_key[0] == '/') {
1757 // parse our key 1761 // parse our key
1758 QStringList list(QStringList::split('/', theKey)); 1762 QStringList list(QStringList::split('/', grp_key));
1759 1763
1760 if (list.count() < 2) { 1764 if (list.count() < 2) {
1761#ifdef QT_CHECK_STATE 1765#ifdef QT_CHECK_STATE
1762 qWarning("QSettings::lastModficationTime: invalid key '%s'", theKey.latin1()); 1766 qWarning("QSettings::lastModificationTime: Invalid key '%s'", grp_key.latin1());
1763#endif // QT_CHECK_STATE 1767#endif // QT_CHECK_STATE
1764 1768
1765 return QDateTime(); 1769 return QDateTime();
1766 } 1770 }
1767 1771
1768 if (list.count() == 2) { 1772 if (list.count() == 2) {
1769 d->heading = list[0]; 1773 d->heading = list[0];
1770 d->group = "General"; 1774 d->group = "General";
@@ -1775,36 +1779,38 @@ QDateTime QSettings::lastModficationTime(const QString &key)
1775 } 1779 }
1776 1780
1777 return d->modificationTime(); 1781 return d->modificationTime();
1778} 1782}
1779 1783
1780 1784
1781/*! 1785/*!
1782 \overload 1786 \overload
1787 \obsolete
1783 1788
1784 Writes the string list entry \a value into key \a key. The \a key 1789 Writes the string list entry \a value into key \a key. The \a key
1785 is created if it doesn't exist. Any previous value is overwritten 1790 is created if it doesn't exist. Any previous value is overwritten
1786 by \a value. The list is stored as a sequence of strings separated 1791 by \a value. The list is stored as a sequence of strings separated
1787 by \a separator (using QStringList::join()), so none of the 1792 by \a separator (using QStringList::join()), so none of the
1788 strings in the list should contain the separator. If the list is 1793 strings in the list should contain the separator. If the list is
1789 empty or null the key's value will be an empty string. 1794 empty or null the key's value will be an empty string.
1790 1795
1791 \warning The list should not contain empty or null strings, as 1796 \warning The list should not contain empty or null strings, as
1792 readListEntry() will use QStringList::split() to recreate the 1797 readListEntry() will use QStringList::split() to recreate the
1793 list. As the documentation states, QStringList::split() will omit 1798 list. As the documentation states, QStringList::split() will omit
1794 empty strings from the list. Because of this, it is impossible to 1799 empty strings from the list. Because of this, it is impossible to
1795 retrieve identical list data that is stored with this function. 1800 retrieve identical list data that is stored with this function.
1796 We recommend using the writeEntry() and readListEntry() overloads 1801 We recommend using the writeEntry() and readListEntry() overloads
1797 that do not take a \a separator argument. 1802 that do not take a \a separator argument.
1798 1803
1804
1799 If an error occurs the settings are left unchanged and FALSE is 1805 If an error occurs the settings are left unchanged and FALSE is
1800 returned; otherwise returns TRUE. 1806 returned; otherwise returns TRUE.
1801 1807
1802 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() 1808 \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry(), QStringList::join()
1803*/ 1809*/
1804bool QSettings::writeEntry(const QString &key, const QStringList &value, 1810bool QSettings::writeEntry(const QString &key, const QStringList &value,
1805 const QChar &separator) 1811 const QChar &separator)
1806{ 1812{
1807 QString s(value.join(separator)); 1813 QString s(value.join(separator));
1808 return writeEntry(key, s); 1814 return writeEntry(key, s);
1809} 1815}
1810 1816
@@ -1834,29 +1840,29 @@ bool QSettings::writeEntry(const QString &key, const QStringList &value)
1834 s+="^e"; // end of element 1840 s+="^e"; // end of element
1835 } 1841 }
1836 return writeEntry(key, s); 1842 return writeEntry(key, s);
1837} 1843}
1838 1844
1839 1845
1840/*! 1846/*!
1841 \overload QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok ) const 1847 \overload QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok ) const
1848 \obsolete
1842 1849
1843 Reads the entry specified by \a key as a string. The \a separator 1850 Reads the entry specified by \a key as a string. The \a separator
1844 is used to create a QStringList by calling QStringList::split(\a 1851 is used to create a QStringList by calling QStringList::split(\a
1845 separator, entry). If \a ok is not 0: \a *ok is set to TRUE if the 1852 separator, entry). If \a ok is not 0: \a *ok is set to TRUE
1846 key was read, otherwise \a *ok is set to FALSE. 1853 if the key was read, otherwise \a *ok is set to FALSE.
1847 1854
1848 \warning As the documentation states, QStringList::split() will 1855 \warning As the documentation states, QStringList::split() will
1849 omit empty strings from the list. Because of this, it is 1856 omit empty strings from the list. Because of this, it is
1850 impossible to retrieve identical list data with this function. We 1857 impossible to retrieve identical list data with this function. We
1851 recommend using the readListEntry() and writeEntry() overloads 1858 recommend using the readListEntry() and writeEntry() overloads
1852 that do not take a \a separator argument. 1859 that do not take a \a separator argument.
1853 1860
1854
1855 Note that if you want to iterate over the list, you should iterate 1861 Note that if you want to iterate over the list, you should iterate
1856 over a copy, e.g. 1862 over a copy, e.g.
1857 \code 1863 \code
1858 QStringList list = mySettings.readListEntry( "size", " " ); 1864 QStringList list = mySettings.readListEntry( "size", " " );
1859 QStringList::Iterator it = list.begin(); 1865 QStringList::Iterator it = list.begin();
1860 while( it != list.end() ) { 1866 while( it != list.end() ) {
1861 myProcessing( *it ); 1867 myProcessing( *it );
1862 ++it; 1868 ++it;
@@ -1944,18 +1950,17 @@ void qt_setSettingsBasePath(const QString &); //qsettings_mac.cpp
1944 1950
1945 The \a product should be the official name of the product. 1951 The \a product should be the official name of the product.
1946 1952
1947 The \a scope should be 1953 The \a scope should be
1948 QSettings::User for user-specific settings, or 1954 QSettings::User for user-specific settings, or
1949 QSettings::Global for system-wide settings (generally 1955 QSettings::Global for system-wide settings (generally
1950 these will be read-only to many users). 1956 these will be read-only to many users).
1951 1957
1952 Not all information is relevant on all systems (e.g. scoping is 1958 Not all information is relevant on all systems.
1953 currently used only if QSettings accesses the Windows registry).
1954*/ 1959*/
1955 1960
1956void QSettings::setPath( const QString &domain, const QString &product, Scope scope ) 1961void QSettings::setPath( const QString &domain, const QString &product, Scope scope )
1957{ 1962{
1958// On Windows, any trailing ".com(\..*)" is stripped from the domain. The 1963// On Windows, any trailing ".com(\..*)" is stripped from the domain. The
1959// Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to 1964// Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to
1960// HKEY_CURRENT_USER. Note that on some installations, not all users can 1965// HKEY_CURRENT_USER. Note that on some installations, not all users can
1961// write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped 1966// write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped
@@ -1975,23 +1980,29 @@ void QSettings::setPath( const QString &domain, const QString &product, Scope sc
1975 1980
1976 QString actualSearchPath; 1981 QString actualSearchPath;
1977 int lastDot = domain.findRev( '.' ); 1982 int lastDot = domain.findRev( '.' );
1978 1983
1979#if defined(Q_WS_WIN) 1984#if defined(Q_WS_WIN)
1980 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; 1985 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product;
1981 insertSearchPath( Windows, actualSearchPath ); 1986 insertSearchPath( Windows, actualSearchPath );
1982#elif !defined(QWS) && defined(Q_OS_MAC) 1987#elif !defined(QWS) && defined(Q_OS_MAC)
1983 QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + "."; 1988 if(lastDot != -1) {
1984 if ( !topLevelDomain.isEmpty() ) 1989 QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + ".";
1985 qt_setSettingsBasePath( topLevelDomain ); 1990 if ( !topLevelDomain.isEmpty() )
1986 actualSearchPath = "/" + domain.left( lastDot ) + product; 1991 qt_setSettingsBasePath( topLevelDomain );
1992 }
1993 actualSearchPath = "/" + domain.left( lastDot ) + "." + product;
1987 insertSearchPath( Mac, actualSearchPath ); 1994 insertSearchPath( Mac, actualSearchPath );
1988#else 1995#else
1989 actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; 1996 if (scope == User)
1997 actualSearchPath = QDir::homeDirPath() + "/.";
1998 else
1999 actualSearchPath = QString(qInstallPathSysconf()) + "/";
2000 actualSearchPath += domain.mid( 0, lastDot ) + "/" + product;
1990 insertSearchPath( Unix, actualSearchPath ); 2001 insertSearchPath( Unix, actualSearchPath );
1991#endif 2002#endif
1992} 2003}
1993 2004
1994/*! 2005/*!
1995 Appends \a group to the current key prefix. 2006 Appends \a group to the current key prefix.
1996 2007
1997 \code 2008 \code