[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-cygwin
Subject:    [PATCH] qsettings_win - registry support
From:       Christian Ehrlicher <Ch.Ehrlicher () gmx ! de>
Date:       2004-09-19 11:27:18
Message-ID: 414D6D16.5010809 () gmx ! de
[Download RAW message or body]

-----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-----

["qsettings_p_h.patch" (text/plain)]

--- ../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;

["qsettings_win.cpp" (text/plain)]

/****************************************************************************
** $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 <winreg.h>
#include <shlwapi.h>

#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


["t1_main_cpp.patch" (text/plain)]

--- ../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 <qapplication.h>
 #include <qpushbutton.h>
+#include <qsettings.h>
 
+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();
 }


_______________________________________________
kde-cygwin mailing list
kde-cygwin@kde.org
https://mail.kde.org/mailman/listinfo/kde-cygwin


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic