@ -1339,145 +1339,150 @@ void Preferences::disableRecursiveDownload(bool disable) {
@@ -1339,145 +1339,150 @@ void Preferences::disableRecursiveDownload(bool disable) {
# ifdef Q_OS_WIN
namespace {
enum REG_SEARCH_TYPE { USER , SYSTEM_32BIT , SYSTEM_64BIT } ;
QStringList getRegSubkeys ( const HKEY & handle ) {
QStringList keys ;
DWORD subkeys_count = 0 ;
DWORD max_subkey_len = 0 ;
long res = : : RegQueryInfoKey ( handle , NULL , NULL , NULL , & subkeys_count , & max_subkey_len , NULL , NULL , NULL , NULL , NULL , NULL ) ;
if ( res = = ERROR_SUCCESS ) {
max_subkey_len + + ; //For null character
LPTSTR key_name = new TCHAR [ max_subkey_len ] ;
for ( uint i = 0 ; i < subkeys_count ; i + + ) {
res = : : RegEnumKeyEx ( handle , 0 , key_name , & max_subkey_len , NULL , NULL , NULL , NULL ) ;
if ( res = = ERROR_SUCCESS )
keys . push_back ( QString : : fromWCharArray ( key_name ) ) ;
}
delete [ ] key_name ;
}
enum REG_SEARCH_TYPE
{
USER ,
SYSTEM_32BIT ,
SYSTEM_64BIT
} ;
return keys ;
}
QStringList getRegSubkeys ( HKEY handle )
{
QStringList keys ;
DWORD cSubKeys = 0 ;
DWORD cMaxSubKeyLen = 0 ;
LONG res = : : RegQueryInfoKeyW ( handle , NULL , NULL , NULL , & cSubKeys , & cMaxSubKeyLen , NULL , NULL , NULL , NULL , NULL , NULL ) ;
if ( res = = ERROR_SUCCESS ) {
cMaxSubKeyLen + + ; // For null character
LPWSTR lpName = new WCHAR [ cMaxSubKeyLen ] ;
DWORD cName ;
for ( DWORD i = 0 ; i < cSubKeys ; + + i ) {
cName = cMaxSubKeyLen ;
res = : : RegEnumKeyExW ( handle , 0 , lpName , & cName , NULL , NULL , NULL , NULL ) ;
if ( res = = ERROR_SUCCESS )
keys . push_back ( QString : : fromWCharArray ( lpName ) ) ;
}
QString getRegValue ( const HKEY & handle , const QString & name = QString ( ) ) {
QString end_result ;
DWORD type = 0 ;
DWORD size = 0 ;
DWORD array_size = 0 ;
delete [ ] lpName ;
}
LPTSTR value_name = NULL ;
if ( ! name . isEmpty ( ) ) {
value_name = new TCHAR [ name . size ( ) + 1 ] ;
name . toWCharArray ( value_name ) ;
value_name [ name . size ( ) ] = ' \0 ' ;
}
return keys ;
}
// Discover the size of the value
: : RegQueryValueEx ( handle , value_name , NULL , & type , NULL , & size ) ;
array_size = size / sizeof ( TCHAR ) ;
if ( size % sizeof ( TCHAR ) )
array_size + + ;
array_size + + ; //For null character
LPTSTR value = new TCHAR [ array_size ] ;
long res = : : RegQueryValueEx ( handle , value_name , NULL , & type , ( LPBYTE ) value , & size ) ;
if ( res = = ERROR_SUCCESS ) {
value [ array_size ] = ' \0 ' ;
end_result = QString : : fromWCharArray ( value ) ;
}
QString getRegValue ( HKEY handle , const QString & name = QString ( ) )
{
QString result ;
DWORD type = 0 ;
DWORD cbData = 0 ;
LPWSTR lpValueName = NULL ;
if ( ! name . isEmpty ( ) ) {
lpValueName = new WCHAR [ name . size ( ) + 1 ] ;
name . toWCharArray ( lpValueName ) ;
lpValueName [ name . size ( ) ] = 0 ;
}
if ( value_name )
delete [ ] value_name ;
if ( value )
delete [ ] value ;
// Discover the size of the value
: : RegQueryValueExW ( handle , lpValueName , NULL , & type , NULL , & cbData ) ;
DWORD cBuffer = ( cbData / sizeof ( WCHAR ) ) + 1 ;
LPWSTR lpData = new WCHAR [ cBuffer ] ;
LONG res = : : RegQueryValueExW ( handle , lpValueName , NULL , & type , ( LPBYTE ) lpData , & cbData ) ;
if ( lpValueName )
delete [ ] lpValueName ;
if ( res = = ERROR_SUCCESS ) {
lpData [ cBuffer ] = 0 ;
result = QString : : fromWCharArray ( lpData ) ;
}
delete [ ] lpData ;
return end_result ;
return result ;
}
QString pythonSearchReg ( const REG_SEARCH_TYPE type ) {
HKEY key_handle1 ;
long res = 0 ;
QString pythonSearchReg ( const REG_SEARCH_TYPE type )
{
HKEY hkRoot ;
if ( type = = USER )
hkRoot = HKEY_CURRENT_USER ;
else
hkRoot = HKEY_LOCAL_MACHINE ;
REGSAM samDesired = KEY_READ ;
if ( type = = SYSTEM_32BIT )
samDesired | = KEY_WOW64_32KEY ;
else if ( type = = SYSTEM_64BIT )
samDesired | = KEY_WOW64_64KEY ;
QString path ;
LONG res = 0 ;
HKEY hkPythonCore ;
res = : : RegOpenKeyExW ( hkRoot , L " SOFTWARE \\ Python \\ PythonCore " , 0 , samDesired , & hkPythonCore ) ;
if ( res = = ERROR_SUCCESS ) {
QStringList versions = getRegSubkeys ( hkPythonCore ) ;
qDebug ( " Python versions nb: %d " , versions . size ( ) ) ;
versions . sort ( ) ;
bool found = false ;
while ( ! found & & ! versions . empty ( ) ) {
const QString version = versions . takeLast ( ) + " \\ InstallPath " ;
LPWSTR lpSubkey = new WCHAR [ version . size ( ) + 1 ] ;
version . toWCharArray ( lpSubkey ) ;
lpSubkey [ version . size ( ) ] = 0 ;
HKEY hkInstallPath ;
res = : : RegOpenKeyExW ( hkPythonCore , lpSubkey , 0 , samDesired , & hkInstallPath ) ;
delete [ ] lpSubkey ;
if ( res = = ERROR_SUCCESS ) {
qDebug ( " Detected possible Python v%s location " , qPrintable ( version ) ) ;
path = getRegValue ( hkInstallPath ) ;
: : RegCloseKey ( hkInstallPath ) ;
if ( ! path . isEmpty ( ) & & QDir ( path ) . exists ( " python.exe " ) ) {
qDebug ( " Found python.exe at %s " , qPrintable ( path ) ) ;
found = true ;
}
}
}
switch ( type ) {
case USER :
res = : : RegOpenKeyEx ( HKEY_CURRENT_USER , TEXT ( " SOFTWARE \\ Python \\ PythonCore " ) , 0 , KEY_READ , & key_handle1 ) ;
break ;
case SYSTEM_32BIT :
res = : : RegOpenKeyEx ( HKEY_LOCAL_MACHINE , TEXT ( " SOFTWARE \\ Python \\ PythonCore " ) , 0 , KEY_READ | KEY_WOW64_32KEY , & key_handle1 ) ;
break ;
case SYSTEM_64BIT :
res = : : RegOpenKeyEx ( HKEY_LOCAL_MACHINE , TEXT ( " SOFTWARE \\ Python \\ PythonCore " ) , 0 , KEY_READ | KEY_WOW64_64KEY , & key_handle1 ) ;
break ;
}
if ( ! found )
path = QString ( ) ;
if ( res = = ERROR_SUCCESS ) {
QStringList versions = getRegSubkeys ( key_handle1 ) ;
qDebug ( " Python versions nb: %d " , versions . size ( ) ) ;
versions . sort ( ) ;
while ( ! versions . empty ( ) ) {
const QString version = versions . takeLast ( ) + " \\ InstallPath " ;
HKEY key_handle2 ;
LPTSTR subkey = new TCHAR [ version . size ( ) + 1 ] ;
version . toWCharArray ( subkey ) ;
subkey [ version . size ( ) ] = ' \0 ' ;
switch ( type ) {
case USER :
res = : : RegOpenKeyEx ( key_handle1 , subkey , 0 , KEY_READ , & key_handle2 ) ;
break ;
case SYSTEM_32BIT :
res = : : RegOpenKeyEx ( key_handle1 , subkey , 0 , KEY_READ | KEY_WOW64_32KEY , & key_handle2 ) ;
break ;
case SYSTEM_64BIT :
res = : : RegOpenKeyEx ( key_handle1 , subkey , 0 , KEY_READ | KEY_WOW64_64KEY , & key_handle2 ) ;
break ;
}
delete [ ] subkey ;
if ( res = = ERROR_SUCCESS ) {
qDebug ( " Detected possible Python v%s location " , qPrintable ( version ) ) ;
QString path = getRegValue ( key_handle2 ) ;
: : RegCloseKey ( key_handle2 ) ;
if ( ! path . isEmpty ( ) & & QDir ( path ) . exists ( " python.exe " ) ) {
qDebug ( " Found python.exe at %s " , qPrintable ( path ) ) ;
: : RegCloseKey ( key_handle1 ) ;
return path ;
}
}
else
: : RegCloseKey ( key_handle2 ) ;
: : RegCloseKey ( hkPythonCore ) ;
}
}
: : RegCloseKey ( key_handle1 ) ;
return QString : : null ;
return path ;
}
}
QString Preferences : : getPythonPath ( ) {
QString path = pythonSearchReg ( USER ) ;
if ( path . isEmpty ( ) )
QString Preferences : : getPythonPath ( )
{
QString path = pythonSearchReg ( USER ) ;
if ( ! path . isEmpty ( ) )
return path ;
path = pythonSearchReg ( SYSTEM_32BIT ) ;
else return path ;
if ( ! path . isEmpty ( ) )
return path ;
if ( path . isEmpty ( ) )
path = pythonSearchReg ( SYSTEM_64BIT ) ;
else return path ;
if ( ! path . isEmpty ( ) )
return path ;
if ( ! path . isEmpty ( ) )
return path ;
// Fallback: Detect python from default locations
QStringList supported_versions ;
supported_versions < < " 32 " < < " 31 " < < " 30 " < < " 27 " < < " 26 " < < " 25 " ;
foreach ( const QString & v , supported_versions ) {
if ( QFile : : exists ( " C:/Python " + v + " /python.exe " ) )
return " C:/Python " + v ;
}
// Fallback: Detect python from default locations
QStringList supported_versions ;
supported_versions < < " 32 " < < " 31 " < < " 30 " < < " 27 " < < " 26 " < < " 25 " ;
foreach ( const QString & v , supported_versions ) {
if ( QFile : : exists ( " C:/Python " + v + " /python.exe " ) )
return " C:/Python " + v ;
}
return QString : : null ;
return QString ( ) ;
}
bool Preferences : : neverCheckFileAssoc ( ) const {