📄 qsettings.cpp
字号:
#else defPath = qInstallPathSysconf();#endif QDir dir(appSettings); if (! dir.exists()) { if (! dir.mkdir(dir.path()))#if defined(QT_CHECK_STATE) qWarning("QSettings: error creating %s", dir.path().latin1());#else ;#endif } if ( !!defPath ) searchPaths.append(defPath); searchPaths.append(dir.path());}QSettingsPrivate::~QSettingsPrivate(){}QSettingsGroup QSettingsPrivate::readGroup(){ QSettingsHeading hd; QSettingsGroup grp; QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading); if (headingsit != headings.end()) hd = *headingsit; QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); if ( !globalScope ) ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { hd.read(fn); hd.insert(fn + "cached", QSettingsGroup()); } } headings.replace(heading, hd); grpit = hd.find(group); if (grpit != hd.end()) grp = *grpit; } else if (hd.count() != 0) grp = *grpit; return grp;}void QSettingsPrivate::removeGroup(const QString &key){ QSettingsHeading hd; QSettingsGroup grp; bool found = FALSE; QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading); if (headingsit != headings.end()) hd = *headingsit; QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); if ( !globalScope ) ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { hd.read(fn); hd.insert(fn + "cached", QSettingsGroup()); } } headings.replace(heading, hd); grpit = hd.find(group); if (grpit != hd.end()) { found = TRUE; grp = *grpit; } } else if (hd.count() != 0) { found = TRUE; grp = *grpit; } if (found) { grp.remove(key); if (grp.count() > 0) hd.replace(group, grp); else hd.remove(group); if (hd.count() > 0) headings.replace(heading, hd); else headings.remove(heading); modified = TRUE; }}void QSettingsPrivate::writeGroup(const QString &key, const QString &value){ QSettingsHeading hd; QSettingsGroup grp; QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading); if (headingsit != headings.end()) hd = *headingsit; QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); if ( !globalScope ) ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { hd.read(fn); hd.insert(fn + "cached", QSettingsGroup()); } } headings.replace(heading, hd); grpit = hd.find(group); if (grpit != hd.end()) grp = *grpit; } else if (hd.count() != 0) grp = *grpit; grp.modified = TRUE; grp.replace(key, value); hd.replace(group, grp); headings.replace(heading, hd); modified = TRUE;}QDateTime QSettingsPrivate::modificationTime(){ QSettingsHeading hd = headings[heading]; QSettingsGroup grp = hd[group]; QDateTime datetime; QStringList::Iterator it = searchPaths.begin(); if ( !globalScope ) ++it; while (it != searchPaths.end()) { QFileInfo fi((*it++) + "/" + heading + "rc"); if (fi.exists() && fi.lastModified() > datetime) datetime = fi.lastModified(); } return datetime;}bool qt_verify_key( const QString &key ){ if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\r\\n]" ) ) ) return FALSE; return TRUE;}static QString groupKey( const QString &group, const QString &key ){ QString grp_key; if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) { // group is empty, or it contains a single '/', so we just return the key if ( key.startsWith( "/" ) ) grp_key = key; else grp_key = "/" + key; } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) { grp_key = group + key; } else { grp_key = group + "/" + key; } return grp_key;}/*! Inserts \a path into the settings search path. The semantics of \a path depends on the system \a s. When \a s is \e Windows and the execution environment is \e not Windows the function does nothing. Similarly when \a s is \e Unix and the execution environment is \e not Unix the function does nothing. When \a s is \e Windows, and the execution environment is Windows, the search path list will be used as the first subfolder of the "Software" folder in the registry. When reading settings the folders are searched forwards from the first folder (listed below) to the last, returning the first settings found, and ignoring any folders for which the user doesn't have read permission. \list 1 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication \i HKEY_CURRENT_USER/Software/MyApplication \i HKEY_LOCAL_MACHINE/Software/MyApplication \endlist \code QSettings settings; settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); settings.writeEntry( "/MyApplication/Tip of the day", TRUE ); \endcode The code above will write the subkey "Tip of the day" into the \e first of the registry folders listed below that is found and for which the user has write permission. \list 1 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication \i HKEY_LOCAL_MACHINE/Software/MyApplication \i HKEY_CURRENT_USER/Software/MyApplication \endlist If a setting is found in the HKEY_CURRENT_USER space, this setting is overwritten independently of write permissions in the HKEY_LOCAL_MACHINE space. When \a s is \e Unix, and the execution environment is Unix, the search path list will be used when trying to determine a suitable filename for reading and writing settings files. By default, there are two entries in the search path: \list 1 \i \c SYSCONF - where \c SYSCONF is a directory specified when configuring Qt; by default it is INSTALL/etc/settings. \i \c $HOME/.qt/ - where \c $HOME is the user's home directory. \endlist All insertions into the search path will go before $HOME/.qt/. For example: \code QSettings settings; settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/etc" ); settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/MyApplication/etc" ); // ... \endcode Will result in a search path of: \list 1 \i SYSCONF \i /opt/MyCompany/share/etc \i /opt/MyCompany/share/MyApplication/etc \i $HOME/.qt \endlist When reading settings the files are searched in the order shown above, with later settings overriding earlier settings. Files for which the user doesn't have read permission are ignored. When saving settings QSettings works in the order shown above, writing to the first settings file for which the user has write permission. Settings under Unix are stored in files whose names are based on the first subkey of the key (not including the search path). The algorithm for creating names is essentially: lowercase the first subkey, replace spaces with underscores and add 'rc', e.g. <tt>/MyCompany/MyApplication/background color</tt> will be stored in <tt>myapplicationrc</tt> (assuming that <tt>/MyCompany</tt> is part of the search path). \sa removeSearchPath()*/void QSettings::insertSearchPath( System s, const QString &path){#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) { d->sysInsertSearchPath( s, path ); return; }#endif#if !defined(Q_WS_WIN) if ( s == Windows ) return;#endif#if !defined(Q_WS_WIN) if ( s == Mac ) return;#endif if ( !qt_verify_key( path ) ) {#if defined(QT_CHECK_STATE) qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );#endif return; }#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd && s != Unix ) {#else if ( s != Unix ) {#endif#if !defined(QWS) && defined(Q_OS_MAC) if(s != Mac) //mac is respected on the mac as well#endif return; } QString realPath = path;#if defined(Q_WS_WIN) QString defPath = d->globalScope ? d->searchPaths.first() : d->searchPaths.last(); realPath = defPath + path;#endif QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last()); if (it != d->searchPaths.end()) { d->searchPaths.insert(it, realPath); }}/*! Removes all occurrences of \a path (using exact matching) from the settings search path for system \a s. Note that the default search paths cannot be removed. \sa insertSearchPath()*/void QSettings::removeSearchPath( System s, const QString &path){ if ( !qt_verify_key( path ) ) {#if defined(QT_CHECK_STATE) qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );#endif return; }#ifdef Q_WS_WIN if ( d->sysd ) { d->sysRemoveSearchPath( s, path ); return; }#endif#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd && s != Unix ) {#else if ( s != Unix ) {#endif#if !defined(QWS) && defined(Q_OS_MAC) if(s != Mac) //mac is respected on the mac as well#endif return; } if (path == d->searchPaths.first() || path == d->searchPaths.last()) return; d->searchPaths.remove(path);}/*! Creates a settings object.*/QSettings::QSettings(){ d = new QSettingsPrivate( Native ); Q_CHECK_PTR(d);#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) d->sysd = 0; d->sysInit();#endif}/*! Creates a settings object. If \a format is 'Ini' the settings will be stored in a text file, using the Unix strategy (see above). If \a format is 'Native', the settings will be stored in a platform specific way (ie. the Windows registry).*/QSettings::QSettings( Format format ){ d = new QSettingsPrivate( format ); Q_CHECK_PTR(d);#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) d->sysd = 0; if ( format == Native ) d->sysInit();#else Q_UNUSED(format);#endif}/*! Destroys the settings object. All modifications made to the settings will automatically be saved.*/QSettings::~QSettings(){ sync();#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) d->sysClear();#endif delete d;}/*! \internal Writes all modifications to the settings to disk. If any errors are encountered, this function returns FALSE, otherwise it will return TRUE.*/bool QSettings::sync(){#if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysSync();#endif if (! d->modified) // fake success return TRUE; bool success = TRUE; QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin(); while (it != d->headings.end()) { // determine filename QSettingsHeading hd(*it); QSettingsHeading::Iterator hdit = hd.begin(); QString filename; QStringList::Iterator pit = d->searchPaths.begin(); if ( !d->globalScope ) ++pit; while (pit != d->searchPaths.end()) { QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_"); QFileInfo di(*pit); if ( !di.exists() ) { QDir dir; dir.mkdir( *pit ); } QFileInfo fi((*pit++) + "/" + filebase + "rc"); if ((fi.exists() && fi.isFile() && fi.isWritable()) || (! fi.exists() && di.isDir() #ifndef Q_WS_WIN && di.isWritable()#else && (qWinVersion() == Qt::WV_XP || di.isWritable())#endif )) { filename = fi.filePath(); break; } } ++it; if ( filename.isEmpty() ) {#ifdef QT_CHECK_STATE qWarning("QSettings::sync: filename is null/empty");#endif // QT_CHECK_STATE success = FALSE; continue; } HANDLE lockfd = openlock( filename, Q_LOCKWRITE ); QFile file( filename + ".tmp" ); if (! file.open(IO_WriteOnly)) {#ifdef QT_CHECK_STATE qWarning("QSettings::sync: failed to open '%s' for writing", file.name().latin1());#endif // QT_CHECK_STATE success = FALSE; continue; } // spew to file QTextStream stream(&file); stream.setEncoding(QTextStream::UnicodeUTF8); while (hdit != hd.end()) { if ((*hdit).count() > 0) { stream << "[" << hdit.key() << "]" << endl; QSettingsGroup grp(*hdit); QSettingsGroup::Iterator grpit = grp.begin(); while (grpit != grp.end()) { QString v = grpit.data(); if ( v.isNull() ) { v = "\\0"; // escape null string } else { v.replace("\\", "\\\\"); // escape backslash v.replace("\n", "\\n"); // escape newlines } stream << grpit.key() << "=" << v << endl; ++grpit; } stream << endl; } ++hdit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -