From 3b5ff71a2743f3991d0497498eda521a1684aad6 Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Sun, 3 May 2015 21:35:22 +0200 Subject: [PATCH] Various improvements to ShellIntegration code. --- etc/Translation/Blank.ts | 4 +- etc/Translation/LameXP_DE.ts | 4 +- etc/Translation/LameXP_ES.ts | 4 +- etc/Translation/LameXP_FR.ts | 4 +- etc/Translation/LameXP_HU.ts | 4 +- etc/Translation/LameXP_IT.ts | 4 +- etc/Translation/LameXP_KR.ts | 4 +- etc/Translation/LameXP_PL.ts | 4 +- etc/Translation/LameXP_RU.ts | 4 +- etc/Translation/LameXP_SV.ts | 4 +- etc/Translation/LameXP_TW.ts | 4 +- etc/Translation/LameXP_UK.ts | 4 +- etc/Translation/LameXP_ZH.ts | 4 +- src/Config.h | 2 +- src/ShellIntegration.cpp | 94 +++++++++++++++++++++++++++--------- src/ShellIntegration.h | 1 + 16 files changed, 98 insertions(+), 51 deletions(-) diff --git a/etc/Translation/Blank.ts b/etc/Translation/Blank.ts index 53c9c116..c70563de 100644 --- a/etc/Translation/Blank.ts +++ b/etc/Translation/Blank.ts @@ -3284,12 +3284,12 @@ ShellIntegration - + Audio File supported by LameXP - + Convert this file with LameXP v%1 diff --git a/etc/Translation/LameXP_DE.ts b/etc/Translation/LameXP_DE.ts index cb914703..3e84ec5c 100644 --- a/etc/Translation/LameXP_DE.ts +++ b/etc/Translation/LameXP_DE.ts @@ -3303,12 +3303,12 @@ ShellIntegration - + Audio File supported by LameXP LameXP Audiodatei - + Convert this file with LameXP v%1 Datei mit LameXP v%1 umwandeln diff --git a/etc/Translation/LameXP_ES.ts b/etc/Translation/LameXP_ES.ts index b756dad3..4f6312ac 100644 --- a/etc/Translation/LameXP_ES.ts +++ b/etc/Translation/LameXP_ES.ts @@ -3303,12 +3303,12 @@ ShellIntegration - + Audio File supported by LameXP Archivo de audio soportado por LameXP - + Convert this file with LameXP v%1 Convertir este archivo con LameXP v%1 diff --git a/etc/Translation/LameXP_FR.ts b/etc/Translation/LameXP_FR.ts index 620a6ce6..87c319e6 100644 --- a/etc/Translation/LameXP_FR.ts +++ b/etc/Translation/LameXP_FR.ts @@ -3313,12 +3313,12 @@ Ouvrir le dossier récursivement... ShellIntegration - + Audio File supported by LameXP Fichier audio pris en charge par LameXP - + Convert this file with LameXP v%1 Convertir ce fichier avec LameXP v%1 diff --git a/etc/Translation/LameXP_HU.ts b/etc/Translation/LameXP_HU.ts index 21c2a271..2c751d27 100644 --- a/etc/Translation/LameXP_HU.ts +++ b/etc/Translation/LameXP_HU.ts @@ -3284,12 +3284,12 @@ ShellIntegration - + Audio File supported by LameXP LameXP által támogatott hangfájl - + Convert this file with LameXP v%1 A fájl konvertálása a LameXP v%1 változatával diff --git a/etc/Translation/LameXP_IT.ts b/etc/Translation/LameXP_IT.ts index b2a1f33a..4d432e52 100644 --- a/etc/Translation/LameXP_IT.ts +++ b/etc/Translation/LameXP_IT.ts @@ -3303,12 +3303,12 @@ ShellIntegration - + Audio File supported by LameXP File audio supportati da LameXP - + Convert this file with LameXP v%1 Convertire il file con LameXP v%1 diff --git a/etc/Translation/LameXP_KR.ts b/etc/Translation/LameXP_KR.ts index 9bb96804..bd591b8d 100644 --- a/etc/Translation/LameXP_KR.ts +++ b/etc/Translation/LameXP_KR.ts @@ -3284,12 +3284,12 @@ ShellIntegration - + Audio File supported by LameXP LameXP에서 지원되는 오디오 파일 - + Convert this file with LameXP v%1 이 파일을 LameXP v%1(으)로 변환 diff --git a/etc/Translation/LameXP_PL.ts b/etc/Translation/LameXP_PL.ts index ba9e650f..253d198a 100644 --- a/etc/Translation/LameXP_PL.ts +++ b/etc/Translation/LameXP_PL.ts @@ -3321,12 +3321,12 @@ ShellIntegration - + Audio File supported by LameXP Pliki dźwiękowe wspierane przez LameXP - + Convert this file with LameXP v%1 Kompresuj ten plik z LameXP v%1 diff --git a/etc/Translation/LameXP_RU.ts b/etc/Translation/LameXP_RU.ts index 3d2230dc..5d6aaa76 100644 --- a/etc/Translation/LameXP_RU.ts +++ b/etc/Translation/LameXP_RU.ts @@ -3328,12 +3328,12 @@ ShellIntegration - + Audio File supported by LameXP Аудио файл, поддерживаемый LameXP - + Convert this file with LameXP v%1 Конвертировать этот файл, используя LameXP v%1 diff --git a/etc/Translation/LameXP_SV.ts b/etc/Translation/LameXP_SV.ts index debb35ba..59456080 100644 --- a/etc/Translation/LameXP_SV.ts +++ b/etc/Translation/LameXP_SV.ts @@ -3304,12 +3304,12 @@ ShellIntegration - + Audio File supported by LameXP Ljudfilen stöds av LameXP - + Convert this file with LameXP v%1 Konvertera denna fil med LameXP v%1 diff --git a/etc/Translation/LameXP_TW.ts b/etc/Translation/LameXP_TW.ts index f8624c7b..1d53bedb 100644 --- a/etc/Translation/LameXP_TW.ts +++ b/etc/Translation/LameXP_TW.ts @@ -3284,12 +3284,12 @@ ShellIntegration - + Audio File supported by LameXP LameXP支持的音頻文件 - + Convert this file with LameXP v%1 轉換此文件與LameXP v%1 diff --git a/etc/Translation/LameXP_UK.ts b/etc/Translation/LameXP_UK.ts index 62ffb86b..aee3bfb4 100644 --- a/etc/Translation/LameXP_UK.ts +++ b/etc/Translation/LameXP_UK.ts @@ -3321,12 +3321,12 @@ ShellIntegration - + Audio File supported by LameXP Аудіофайл, що підтримується LameXP - + Convert this file with LameXP v%1 Конвертувати файл за допомогою LameXP v%1 diff --git a/etc/Translation/LameXP_ZH.ts b/etc/Translation/LameXP_ZH.ts index 9da77f46..373b40e1 100644 --- a/etc/Translation/LameXP_ZH.ts +++ b/etc/Translation/LameXP_ZH.ts @@ -3284,12 +3284,12 @@ ShellIntegration - + Audio File supported by LameXP LameXP支持的音频文件 - + Convert this file with LameXP v%1 用LameXP v%1转换此文件 diff --git a/src/Config.h b/src/Config.h index 30bc52d0..7228b04b 100644 --- a/src/Config.h +++ b/src/Config.h @@ -35,7 +35,7 @@ #define VER_LAMEXP_MINOR_LO 2 #define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_PATCH 1 -#define VER_LAMEXP_BUILD 1716 +#define VER_LAMEXP_BUILD 1719 #define VER_LAMEXP_CONFG 1700 /////////////////////////////////////////////////////////////////////////////// diff --git a/src/ShellIntegration.cpp b/src/ShellIntegration.cpp index dead7aa0..8db9754d 100644 --- a/src/ShellIntegration.cpp +++ b/src/ShellIntegration.cpp @@ -49,6 +49,14 @@ static const char *g_lamexpFileType = "LameXP.SupportedAudioFile"; //Mutex QMutex ShellIntegration::m_mutex; +//State values +static const int STATE_ENABLED = 1; +static const int STATE_UNKNOWN = 0; +static const int STATE_DISABLD = -1; + +//State +volatile int ShellIntegration::m_state = STATE_UNKNOWN; + //Macros #define REG_WRITE_STRING(KEY, STR) RegSetValueEx(key, NULL, NULL, REG_SZ, reinterpret_cast(STR.utf16()), (STR.size() + 1) * sizeof(wchar_t)) @@ -77,6 +85,12 @@ void ShellIntegration::install(bool async) //Serialize QMutexLocker lock(&m_mutex); + //Checking + if(m_state == STATE_ENABLED) + { + return; /*already enabled, don't enable again!*/ + } + //Init some consts const QString lamexpFileType(g_lamexpFileType); const QString lamexpFileInfo(tr("Audio File supported by LameXP")); @@ -85,25 +99,30 @@ void ShellIntegration::install(bool async) const QString lamexpShellAction(g_lamexpShellAction); //Register the LameXP file type - MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1") .arg(lamexpFileType), QString(), lamexpFileInfo); - MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell") .arg(lamexpFileType), QString(), lamexpShellAction); - MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2") .arg(lamexpFileType, lamexpShellAction), QString(), lamexpShellText); - MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2\\command").arg(lamexpFileType, lamexpShellAction), QString(), lamexpShellCommand); + const bool ok1 = MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1") .arg(lamexpFileType), QString(), lamexpFileInfo); + const bool ok2 = MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell") .arg(lamexpFileType), QString(), lamexpShellAction); + const bool ok3 = MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2") .arg(lamexpFileType, lamexpShellAction), QString(), lamexpShellText); + const bool ok4 = MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2\\command").arg(lamexpFileType, lamexpShellAction), QString(), lamexpShellCommand); + if(!(ok1 && ok2 && ok3 && ok4)) + { + qWarning("Failed to create LameXP file type!"); + return; + } //Detect supported file types QStringList types; detectTypes(lamexpFileType, lamexpShellAction, types); //Add LameXP shell action to all supported file types - while(!types.isEmpty()) + for(QStringList::ConstIterator iter = types.constBegin(); iter != types.constEnd(); iter++) { - QString currentType = types.takeFirst(); - MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2") .arg(currentType, lamexpShellAction), QString(), lamexpShellText); - MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2\\command").arg(currentType, lamexpShellAction), QString(), lamexpShellCommand); + MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2") .arg((*iter), lamexpShellAction), QString(), lamexpShellText); + MUtils::Registry::reg_value_write(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2\\command").arg((*iter), lamexpShellAction), QString(), lamexpShellCommand); } //Shell notification MUtils::OS::shell_change_notification(); + m_state = STATE_ENABLED; } void ShellIntegration::remove(bool async) @@ -118,6 +137,12 @@ void ShellIntegration::remove(bool async) //Serialize QMutexLocker lock(&m_mutex); + //Checking + if(m_state == STATE_DISABLD) + { + return; /*already enabled, don't enable again!*/ + } + //Init some consts const QString lamexpFileType(g_lamexpFileType); const QString lamexpShellAction(g_lamexpShellAction); @@ -133,16 +158,28 @@ void ShellIntegration::remove(bool async) } //Remove shell action from all file types - while(!fileTypes.isEmpty()) + for(QStringList::ConstIterator iter = fileTypes.constBegin(); iter != fileTypes.constEnd(); iter++) { - MUtils::Registry::reg_key_delete(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2").arg(fileTypes.takeFirst(), lamexpShellAction)); + MUtils::Registry::reg_key_delete(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\shell\\%2").arg((*iter), lamexpShellAction)); + + //Remove from sub-tree too + QStringList subTypes; + if(MUtils::Registry::reg_enum_subkeys(MUtils::Registry::root_user, QString("Software\\Classes\\%1").arg(*iter), subTypes)) + { + for(QStringList::ConstIterator iter2 = subTypes.constBegin(); iter2 != subTypes.constEnd(); iter2++) + { + MUtils::Registry::reg_key_delete(MUtils::Registry::root_user, QString("Software\\Classes\\%1\\%2\\shell\\%3").arg((*iter), (*iter2), lamexpShellAction)); + } + } } + //Unregister LameXP file type MUtils::Registry::reg_key_delete(MUtils::Registry::root_user, QString("Software\\Classes\\%1").arg(lamexpFileType)); //Shell notification MUtils::OS::shell_change_notification(); + m_state = STATE_DISABLD; } //////////////////////////////////////////////////////////// @@ -152,33 +189,36 @@ void ShellIntegration::remove(bool async) void ShellIntegration::detectTypes(const QString &lamexpFileType, const QString &lamexpShellAction, QStringList &nativeTypes) { nativeTypes.clear(); - QStringList supportedTypes = DecoderRegistry::getSupportedTypes(); - QStringList extensions; + const QStringList supportedTypes = DecoderRegistry::getSupportedTypes(); + const QString progId = "Progid"; QRegExp regExp1("\\((.+)\\)"); QRegExp regExp2("(\\.\\w+)"); //Find all supported file extensions - while(!supportedTypes.isEmpty()) + QStringList extensions; + for(QStringList::ConstIterator iter = supportedTypes.constBegin(); iter != supportedTypes.constEnd(); iter++) { - if(regExp1.lastIndexIn(supportedTypes.takeFirst()) > 0) + if(regExp1.lastIndexIn(*iter) > 0) { int lastIndex = 0; while((lastIndex = regExp2.indexIn(regExp1.cap(1), lastIndex) + 1) >= 1) { - extensions.append(regExp2.cap(1)); + if(!extensions.contains(regExp2.cap(1), Qt::CaseInsensitive)) + { + extensions.append(regExp2.cap(1)); + } } } } //Map supported extensions to native types - while(!extensions.isEmpty()) + for(QStringList::ConstIterator iter = extensions.constBegin(); iter != extensions.constEnd(); iter++) { - const QString currentExt = extensions.takeFirst(); - QString currentType; - if(MUtils::Registry::reg_value_read(MUtils::Registry::root_classes, currentExt, QString(), currentType)) + if(MUtils::Registry::reg_value_read(MUtils::Registry::root_classes, (*iter), QString(), currentType)) { + currentType = QDir::toNativeSeparators(currentType); if((currentType.compare(lamexpFileType, Qt::CaseInsensitive) != 0) && (!nativeTypes.contains(currentType, Qt::CaseInsensitive))) { nativeTypes.append(currentType); @@ -186,22 +226,28 @@ void ShellIntegration::detectTypes(const QString &lamexpFileType, const QString } else { - MUtils::Registry::reg_value_write(MUtils::Registry::root_user, currentExt, QString(), lamexpFileType); + MUtils::Registry::reg_value_write(MUtils::Registry::root_user, (*iter), QString(), lamexpFileType); } - if(MUtils::Registry::reg_value_read(MUtils::Registry::root_user, QString("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%1\\UserChoice").arg(currentExt), QString(), currentType)) + if(MUtils::Registry::reg_value_read(MUtils::Registry::root_user, QString("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%1\\UserChoice").arg(*iter), progId, currentType)) { + currentType = QDir::toNativeSeparators(currentType); if((currentType.compare(lamexpFileType, Qt::CaseInsensitive) != 0) && (!nativeTypes.contains(currentType, Qt::CaseInsensitive))) { nativeTypes.append(currentType); } } - if(MUtils::Registry::reg_value_read(MUtils::Registry::root_user, QString("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%1\\OpenWithProgids").arg(currentExt), QString(), currentType)) + QStringList progids; + if(MUtils::Registry::reg_enum_values(MUtils::Registry::root_user, QString("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%1\\OpenWithProgids").arg(*iter), progids)) { - if((currentType.compare(lamexpFileType, Qt::CaseInsensitive) != 0) && (!nativeTypes.contains(currentType, Qt::CaseInsensitive))) + for(QStringList::ConstIterator iter2 = progids.constBegin(); iter2 != progids.constEnd(); iter2++) { - nativeTypes.append(currentType); + currentType = QDir::toNativeSeparators(currentType); + if((iter2->compare(lamexpFileType, Qt::CaseInsensitive) != 0) && (!nativeTypes.contains((*iter2), Qt::CaseInsensitive))) + { + nativeTypes.append(*iter2); + } } } } diff --git a/src/ShellIntegration.h b/src/ShellIntegration.h index 0d89caf5..151bef21 100644 --- a/src/ShellIntegration.h +++ b/src/ShellIntegration.h @@ -41,4 +41,5 @@ private: static void detectTypes(const QString &lamexpFileType, const QString &lamexpShellAction, QStringList &nativeTypes); static QMutex m_mutex; + static volatile int m_state; };