From kde-cygwin Sun Sep 19 11:27:18 2004 From: Christian Ehrlicher Date: Sun, 19 Sep 2004 11:27:18 +0000 To: kde-cygwin Subject: [PATCH] qsettings_win - registry support Message-Id: <414D6D16.5010809 () gmx ! de> X-MARC-Message: https://marc.info/?l=kde-cygwin&m=109559331726708 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--------------080502030900060506000409" This is a multi-part message in MIME format. --------------080502030900060506000409 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello I've finally qsettings registry support ready. It looked more complicated than it was :) There is full support for ansi and unicode and I've tested it with a few settings in tutorial/t1 (see attached main.cpp). Maybe someone could cross-check the behaviour with qt3.2.1nc. The qsettings_p.h - patch just comments out four functions which are now implemented in qsettings.cpp. I wonder why no compiler complaints about this... Other topic: What licensing informations should the files we create have? I think "(c) by Trolltech" isn't the correct one, or? In qsettings_win.cpp there is an example how I think it can be, but you can make other suggestions. @Peter tutorial/t1: When I resize the app-window, sometimes the text in the button isn't displayed correctly. But it has nothing to do with the size... Cheers, Christian -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFBTW0WnNKwkgf+zVMRAn43AKCTeMfHxME+fNX6YPGRr/LUJNeCHgCeN+QQ ibC6r8oJT8piGllKLZyNt/c= =IH36 -----END PGP SIGNATURE----- --------------080502030900060506000409 Content-Type: text/plain; name="qsettings_p_h.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qsettings_p_h.patch" --- ../qt-3/src/tools/qsettings_p.h 2004-08-27 23:08:18.000000000 +0200 +++ src/tools/qsettings_p.h 2004-09-18 23:17:42.000000000 +0200 @@ -113,20 +113,22 @@ void sysInit(); void sysClear(); +/* obsolete functions since already handled in public class + QStringList sysReadListEntry( const QString &, bool * = 0 ) const; + QStringList sysReadListEntry( const QString &, const QChar& sep, bool * = 0 ) const; + bool sysWriteEntry( const QString &, const QStringList &, const QChar& sep ) + bool sysWriteEntry( const QString&key, const QStringList&data ) +*/ #if !defined(Q_NO_BOOL_TYPE) bool sysWriteEntry( const QString &, bool ); #endif bool sysWriteEntry( const QString &, double ); bool sysWriteEntry( const QString &, int ); bool sysWriteEntry( const QString &, const QString & ); - bool sysWriteEntry( const QString &, const QStringList & ); - bool sysWriteEntry( const QString &, const QStringList &, const QChar& sep ); QStringList sysEntryList(const QString &) const; QStringList sysSubkeyList(const QString &) const; - QStringList sysReadListEntry( const QString &, bool * = 0 ) const; - QStringList sysReadListEntry( const QString &, const QChar& sep, bool * = 0 ) const; QString sysReadEntry( const QString &, const QString &def = QString::null, bool * = 0 ) const; int sysReadNumEntry( const QString &, int def = 0, bool * = 0 ) const; double sysReadDoubleEntry( const QString &, double def = 0, bool * = 0 ) const; --------------080502030900060506000409 Content-Type: text/plain; name="qsettings_win.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qsettings_win.cpp" /**************************************************************************** ** $Id: qsettings_win.cpp,v 1.1.2.4.2.1 2004/08/28 00:19:40 habacker Exp $ ** ** Implementation of QSettingsPrivate class for Windows ** ** Created: 2004.09.18 ** ** Copyright (C) 2004 Christian Ehrlicher ** ** This file is part of the tools module of the ** "Qt GUI Toolkit for Windows licensed under the GPL or QPL". ** ** For more informations about the project see: ** http://kde-cygwin.sourceforge.net/qt3-win32/ ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** **********************************************************************/ #include "qsettings.h" #ifndef QT_NO_SETTINGS #include "qt_windows.h" #include #include #include "qstring.h" #include "qregexp.h" #include "qsettings_p.h" /* MSVC++ 6.0 doesn't define this :( */ #ifndef REG_QWORD #define REG_QWORD_LITTLE_ENDIAN (11) #define REG_QWORD (11) #endif bool qt_verify_key( const QString & ); //qsettings.cpp class QSettingsSysPrivate { public: QSettingsSysPrivate(); QStringList searchPaths; /* Helper functions */ /* Opens a key, first tries in HKEY_CURRENT_USER/Software, then in HKEY_LOCAL_MACHINE/Software unless global == true (than only HKLM). If key doesn't exist, it is created --> for writing. */ HKEY createKey( const QString &key, REGSAM access , QString &value, bool global ); /* Opens a key, first tries in HKEY_CURRENT_USER/Software, then in HKEY_LOCAL_MACHINE/Software unless global == true (than only HKLM). If key doesn't exist, open will fail --> for reading. */ HKEY openKey( const QString &key, REGSAM access , QString &value, bool global ); /* Splits a key in main_key and value */ void splitKey ( const QString &key, QString &main_key, QString &value ); }; QSettingsSysPrivate::QSettingsSysPrivate() {} HKEY QSettingsSysPrivate::createKey( const QString &key, REGSAM access, QString &value , bool global ) { const HKEY scopes[ 2 ] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }; HKEY res_key = NULL; QString main_key; splitKey( key, main_key, value ); QString whole_key = "Software\\" + main_key; for ( QStringList::Iterator it = searchPaths.fromLast(); it != searchPaths.end(); --it ) { QString search_key = ( *it ) + main_key; //try local, then global (unless global == true, then just global) int i = global ? 1 : 0; for ( i ; i < 2; i++ ) { long ret = QT_WA_INLINE( RegCreateKeyExW( scopes[ i ], whole_key.ucs2(), 0, NULL, REG_OPTION_NON_VOLATILE, access, NULL, &res_key , NULL ), RegCreateKeyExA( scopes[ i ], whole_key.latin1(), 0, NULL, REG_OPTION_NON_VOLATILE, access, NULL, &res_key , NULL ) ); if ( ret == ERROR_SUCCESS ) return res_key; } } return res_key; } HKEY QSettingsSysPrivate::openKey( const QString &key, REGSAM access, QString &value , bool global ) { const HKEY scopes[ 2 ] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }; HKEY res_key = NULL; QString main_key; splitKey( key, main_key, value ); QString whole_key = "Software\\" + main_key; for ( QStringList::Iterator it = searchPaths.fromLast(); it != searchPaths.end(); --it ) { QString search_key = ( *it ) + main_key; //try local, then global (unless global == true, then just global) int i = global ? 1 : 0; for ( i ; i < 2; i++ ) { long ret = QT_WA_INLINE( RegOpenKeyExW( scopes[ i ], whole_key.ucs2(), 0, access, &res_key ), RegOpenKeyExA( scopes[ i ], whole_key.latin1(), 0, access, &res_key ) ); if ( ret == ERROR_SUCCESS ) return res_key; } } return res_key; } void QSettingsSysPrivate::splitKey ( const QString &key, QString &main_key, QString &value ) { int pos = key.findRev( QRegExp( "(/|\\\\)" ) ); if ( pos == -1 ) { main_key = QString( "" ); value = key; } else { main_key = key.left( pos ); value = key.right( key.length() - pos - 1 ); } while ( ( main_key[ 0 ] == '/' ) || ( main_key[ 0 ] == '\\' ) ) main_key.remove( 0, 1 ); while ( ( main_key.right( 1 ) == "/" ) || ( main_key.right( 1 ) == "\\" ) ) main_key.truncate( main_key.length() - 1 ); } /* from qsettings_mac.cpp 3.3.2 */ void QSettingsPrivate::sysInit( void ) { sysd = new QSettingsSysPrivate; Q_CHECK_PTR( sysd ); sysInsertSearchPath( QSettings::Windows, "" ); } /* from qsettings_mac.cpp 3.3.2 */ void QSettingsPrivate::sysClear( void ) { delete sysd; sysd = NULL; } /* obsolete functions since already handled in public class QStringList sysReadListEntry( const QString &, bool * = 0 ) const; QStringList sysReadListEntry( const QString &, const QChar& sep, bool * = 0 ) const; bool sysWriteEntry( const QString &, const QStringList &, const QChar& sep ) bool sysWriteEntry( const QString&key, const QStringList&data ) */ #if !defined(Q_NO_BOOL_TYPE) bool QSettingsPrivate::sysWriteEntry( const QString &key, bool data ) { return sysWriteEntry( key, ( int ) data ); } #endif bool QSettingsPrivate::sysWriteEntry( const QString &key, double data ) { #ifdef QT_CHECK_STATE if ( key.isNull() || key.isEmpty() ) { qWarning( "QSettingsPrivate::sysWriteEntry: invalid null/empty key." ); return false; } #endif // QT_CHECK_STATE long ret = -1; QString value; HKEY hkey = sysd->createKey( key, KEY_SET_VALUE , value , globalScope ); if ( hkey ) { ret = QT_WA_INLINE( RegSetValueExW( hkey, value.ucs2(), 0, REG_QWORD, ( LPBYTE ) & data, sizeof( double ) ), RegSetValueExA( hkey, value.latin1(), 0, REG_QWORD, ( LPBYTE ) & data, sizeof( double ) ) ); RegCloseKey( hkey ); } return ( ret == ERROR_SUCCESS ); } bool QSettingsPrivate::sysWriteEntry( const QString &key, int data ) { #ifdef QT_CHECK_STATE if ( key.isNull() || key.isEmpty() ) { qWarning( "QSettingsPrivate::sysWriteEntry: invalid null/empty key." ); return false; } #endif // QT_CHECK_STATE long ret = -1; QString value; HKEY hkey = sysd->createKey( key, KEY_SET_VALUE , value , globalScope ); if ( hkey ) { long ret = QT_WA_INLINE( RegSetValueExW( hkey, value.ucs2(), 0, REG_DWORD, ( LPBYTE ) & data, sizeof( int ) ), RegSetValueExA( hkey, value.latin1(), 0, REG_DWORD, ( LPBYTE ) & data, sizeof( int ) ) ); RegCloseKey( hkey ); } return ( ret == ERROR_SUCCESS ); } bool QSettingsPrivate::sysWriteEntry( const QString &key, const QString &data ) { #ifdef QT_CHECK_STATE if ( key.isNull() || key.isEmpty() ) { qWarning( "QSettingsPrivate::sysWriteEntry: invalid null/empty key." ); return false; } #endif // QT_CHECK_STATE long ret = -1; QString value; HKEY hkey = sysd->createKey( key, KEY_SET_VALUE , value , globalScope ); if ( hkey ) { int len = ( data.length() + 1 ) * sizeof( TCHAR ); long ret = QT_WA_INLINE( RegSetValueExW( hkey, value.ucs2(), 0, REG_SZ, ( LPBYTE ) data.ucs2(), len ), RegSetValueExA( hkey, value.latin1(), 0, REG_SZ, ( LPBYTE ) data.latin1(), len ) ); RegCloseKey( hkey ); } return ( ret == ERROR_SUCCESS ); } QStringList QSettingsPrivate::sysEntryList( const QString &key ) const { QString value; QStringList list; HKEY hkey = sysd->openKey( key + "\\", KEY_QUERY_VALUE, value, globalScope ); if ( hkey ) { int idx = 0; unsigned long count = QT_WA_INLINE( 16383, 260 ); QByteArray ba( ( count + 1 ) * sizeof( TCHAR ) ); while ( QT_WA_INLINE( RegEnumValueW( hkey, idx, ( LPTSTR ) ba.data(), &count, NULL, NULL, NULL, NULL ), RegEnumValueA( hkey, idx, ( LPSTR ) ba.data(), &count, NULL, NULL, NULL, NULL ) ) == ERROR_SUCCESS ) { list.append ( QT_WA_INLINE( QString::fromUcs2( ( LPCTSTR ) ba.data() ), QString::fromLatin1( ( LPCSTR ) ba.data() ) ) ); idx++; count = QT_WA_INLINE( 16383, 260 ); /* !! */ } RegCloseKey( hkey ); } return list; } QStringList QSettingsPrivate::sysSubkeyList( const QString &key ) const { QString value; QStringList list; HKEY hkey = sysd->openKey( key + "\\", KEY_ENUMERATE_SUB_KEYS, value, globalScope ); if ( hkey ) { int idx = 0; unsigned long count = 255; QByteArray ba( ( count + 1 ) * sizeof( TCHAR ) ); FILETIME time; while ( QT_WA_INLINE( RegEnumKeyExW( hkey, idx, ( LPTSTR ) ba.data(), &count, NULL, NULL, NULL, &time ), RegEnumKeyExA( hkey, idx, ( LPSTR ) ba.data(), &count, NULL, NULL, NULL, &time ) ) == ERROR_SUCCESS ) { list.append ( QT_WA_INLINE( QString::fromUcs2( ( LPCTSTR ) ba.data() ), QString::fromLatin1( ( LPCSTR ) ba.data() ) ) ); idx++; count = 255; /* !! */ } RegCloseKey( hkey ); } return list; } QString QSettingsPrivate::sysReadEntry( const QString &key, const QString &def, bool *ok ) const { #ifdef QT_CHECK_STATE if ( key.isNull() || key.isEmpty() ) { qWarning( "QSettingsPrivate::sysReadEntry: invalid null/empty key." ); if ( ok ) * ok = FALSE; return def; } #endif // QT_CHECK_STATE QString value; if ( ok ) * ok = FALSE; HKEY hkey = sysd->openKey( key, KEY_QUERY_VALUE , value, globalScope ); if ( hkey ) { unsigned long ret, len = sizeof( int ); /* First get the size of the data */ ret = QT_WA_INLINE( RegQueryValueExW( hkey, value.ucs2(), NULL, NULL, NULL, &len ), RegQueryValueExA( hkey, value.latin1(), NULL, NULL, NULL, &len ) ); if ( ret != ERROR_SUCCESS ) return def; /* now create buffer to store data */ QByteArray ba( len + 1 ); /* +1 to be sure :) */ ret = QT_WA_INLINE( RegQueryValueExW( hkey, value.ucs2(), NULL, NULL, ( LPBYTE ) ba.data(), &len ), RegQueryValueExA( hkey, value.latin1(), NULL, NULL, ( LPBYTE ) ba.data(), &len ) ); RegCloseKey( hkey ); if ( ( ret == ERROR_SUCCESS ) ) { QString str; str = QT_WA_INLINE( QString::fromUcs2( ( LPCTSTR ) ba.data() ), QString::fromLatin1( ( LPCSTR ) ba.data() ) ); if ( ok ) * ok = true; return str; } } return def; } int QSettingsPrivate::sysReadNumEntry( const QString &key, int def, bool * ok ) const { #ifdef QT_CHECK_STATE if ( key.isNull() || key.isEmpty() ) { qWarning( "QSettingsPrivate::sysReadNumEntry: invalid null/empty key." ); if ( ok ) * ok = false; return def; } #endif // QT_CHECK_STATE QString value; if ( ok ) * ok = false; HKEY hkey = sysd->openKey( key, KEY_QUERY_VALUE , value , globalScope ); if ( hkey ) { int num; unsigned long ret, len = sizeof( int ); ret = QT_WA_INLINE( RegQueryValueExW( hkey, value.ucs2(), NULL, NULL, ( LPBYTE ) & num, &len ), RegQueryValueExA( hkey, value.latin1(), NULL, NULL, ( LPBYTE ) & num, &len ) ); RegCloseKey( hkey ); if ( ( ret == ERROR_SUCCESS ) && ( len == sizeof( int ) ) ) { if ( ok ) * ok = true; return num; } } return def; } double QSettingsPrivate::sysReadDoubleEntry( const QString &key, double def, bool * ok ) const { #ifdef QT_CHECK_STATE if ( key.isNull() || key.isEmpty() ) { qWarning( "QSettingsPrivate::sysReadDoubleEntry: invalid null/empty key." ); if ( ok ) * ok = false; return def; } #endif // QT_CHECK_STATE QString value; if ( ok ) * ok = false; HKEY hkey = sysd->openKey( key, KEY_QUERY_VALUE , value, globalScope ); if ( hkey ) { double num; unsigned long ret, len = sizeof( double ); ret = QT_WA_INLINE( RegQueryValueExW( hkey, value.ucs2(), NULL, NULL, ( LPBYTE ) & num, &len ), RegQueryValueExA( hkey, value.latin1(), NULL, NULL, ( LPBYTE ) & num, &len ) ); RegCloseKey( hkey ); if ( ( ret == ERROR_SUCCESS ) && ( len == sizeof( double ) ) ) { if ( ok ) * ok = true; return num; } } return def; } bool QSettingsPrivate::sysReadBoolEntry( const QString &key, bool def, bool * ok ) const { #ifdef QT_CHECK_STATE if ( key.isNull() || key.isEmpty() ) { qWarning( "QSettingsPrivate::sysReadBoolEntry: invalid null/empty key." ); if ( ok ) * ok = false; return def; } #endif // QT_CHECK_STATE QString value; if ( ok ) * ok = false; HKEY hkey = sysd->openKey( key, KEY_QUERY_VALUE , value, globalScope ); if ( hkey ) { bool num; unsigned long ret, len = sizeof( bool ); ret = QT_WA_INLINE( RegQueryValueExW( hkey, value.ucs2(), NULL, NULL, ( LPBYTE ) & num, &len ), RegQueryValueExA( hkey, value.latin1(), NULL, NULL, ( LPBYTE ) & num, &len ) ); RegCloseKey( hkey ); if ( ( ret == ERROR_SUCCESS ) && ( len == sizeof( bool ) ) ) { if ( ok ) * ok = true; return num; } } return def; } bool QSettingsPrivate::sysRemoveEntry( const QString &key ) { QString value; HKEY hkey = sysd->openKey( key , KEY_SET_VALUE, value, globalScope ); if ( hkey ) { /* This just deletes a value, not a subkey ... */ long ret = QT_WA_INLINE( RegDeleteValueW( hkey, value.ucs2() ), RegDeleteValueA( hkey, value.latin1() ) ); RegCloseKey( hkey ); return ( ret == ERROR_SUCCESS ); } return false; } /* what to do here? */ bool QSettingsPrivate::sysSync( void ) { return true; } /* from qsettings_mac.cpp 3.3.2 */ void QSettingsPrivate::sysInsertSearchPath( QSettings::System s, const QString &path ) { if ( s != QSettings::Windows ) return ; if ( !path.isEmpty() && !qt_verify_key( path ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); #endif return ; } QString realpath = path; while ( ( realpath.right( 1 ) == "/" ) || ( realpath.right( 1 ) == "\\" ) ) realpath.truncate( realpath.length() - 1 ); sysd->searchPaths.append( realpath ); } /* from qsettings_mac.cpp 3.3.2 */ void QSettingsPrivate::sysRemoveSearchPath( QSettings::System s, const QString &path ) { if ( s != QSettings::Windows ) return ; QString realpath = path; while ( realpath.right( 1 ) == "/" ) realpath.truncate( realpath.length() - 1 ); sysd->searchPaths.remove( realpath ); } #endif //QT_NO_SETTINGS --------------080502030900060506000409 Content-Type: text/plain; name="t1_main_cpp.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="t1_main_cpp.patch" --- ../qt-3/tutorial/t1/main.cpp 2002-04-18 21:46:04.000000000 +0200 +++ tutorial/t1/main.cpp 2004-09-19 09:41:40.000000000 +0200 @@ -6,7 +6,11 @@ #include #include +#include +const char* reg_entry1 = "Trolltech\\Qt Designer\\3.2\\FileFilter"; +const char* reg_entry2 = "Trolltech\\Qt Designer\\3.2\\DatabaseAutoEdit"; +const char* reg_entry3 = "Trolltech\\Qt Designer\\3.2"; int main( int argc, char **argv ) { @@ -17,5 +21,13 @@ a.setMainWidget( &hello ); hello.show(); + QSettings setting; + QString str = setting.readEntry(reg_entry1); + int num = setting.readNumEntry(reg_entry2); + QStringList list = setting.subkeyList(reg_entry3); + list = setting.entryList(reg_entry3); + setting.removeEntry(reg_entry2); + setting.writeEntry(reg_entry2,0); + return a.exec(); } --------------080502030900060506000409 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kde-cygwin mailing list kde-cygwin@kde.org https://mail.kde.org/mailman/listinfo/kde-cygwin --------------080502030900060506000409--