diff --git a/LameXP.vcproj b/LameXP.vcproj index e4e25965..c1a145e8 100644 --- a/LameXP.vcproj +++ b/LameXP.vcproj @@ -66,7 +66,7 @@ + + + + + + + + + + + diff --git a/etc/Translation/Blank.ts b/etc/Translation/Blank.ts index 6b051acd..d699a261 100644 --- a/etc/Translation/Blank.ts +++ b/etc/Translation/Blank.ts @@ -1436,6 +1436,17 @@ + + ShellIntegration + + Audio File supported by LameXP + + + + Convert this file with LameXP v4 + + + SplashScreen diff --git a/etc/Translation/LameXP_DE.ts b/etc/Translation/LameXP_DE.ts index ff52f398..1ef42c37 100644 --- a/etc/Translation/LameXP_DE.ts +++ b/etc/Translation/LameXP_DE.ts @@ -1437,6 +1437,17 @@ Status + + ShellIntegration + + Audio File supported by LameXP + LameXP Audio-Datei + + + Convert this file with LameXP v4 + Diese Datei mit LameXP v4 umwandeln + + SplashScreen diff --git a/etc/Translation/LameXP_ES.ts b/etc/Translation/LameXP_ES.ts index 9381a123..5920701e 100644 --- a/etc/Translation/LameXP_ES.ts +++ b/etc/Translation/LameXP_ES.ts @@ -1437,6 +1437,17 @@ Estado + + ShellIntegration + + Audio File supported by LameXP + + + + Convert this file with LameXP v4 + + + SplashScreen diff --git a/etc/Translation/LameXP_FR.ts b/etc/Translation/LameXP_FR.ts index 549a9aaa..1cfe3a11 100644 --- a/etc/Translation/LameXP_FR.ts +++ b/etc/Translation/LameXP_FR.ts @@ -1439,6 +1439,17 @@ Votre dossier TEMP est situé ici: Statut + + ShellIntegration + + Audio File supported by LameXP + + + + Convert this file with LameXP v4 + + + SplashScreen diff --git a/etc/Translation/LameXP_IT.ts b/etc/Translation/LameXP_IT.ts index aa2432f9..21268b61 100644 --- a/etc/Translation/LameXP_IT.ts +++ b/etc/Translation/LameXP_IT.ts @@ -1437,6 +1437,17 @@ Stato + + ShellIntegration + + Audio File supported by LameXP + + + + Convert this file with LameXP v4 + + + SplashScreen diff --git a/res/localization/LameXP_DE.qm b/res/localization/LameXP_DE.qm index abaaaf4c..ab83b1e3 100644 Binary files a/res/localization/LameXP_DE.qm and b/res/localization/LameXP_DE.qm differ diff --git a/src/Config.h b/src/Config.h index 67cc4044..c5e12ee7 100644 --- a/src/Config.h +++ b/src/Config.h @@ -25,7 +25,7 @@ #define VER_LAMEXP_MAJOR 4 #define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_LO 0 -#define VER_LAMEXP_BUILD 270 +#define VER_LAMEXP_BUILD 273 #define VER_LAMEXP_SUFFIX Beta-2 /* diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp index 3cb85540..9fdfbe34 100644 --- a/src/Dialog_MainWindow.cpp +++ b/src/Dialog_MainWindow.cpp @@ -37,6 +37,7 @@ #include "Model_FileSystem.h" #include "WinSevenTaskbar.h" #include "Registry_Decoder.h" +#include "ShellIntegration.h" //Qt includes #include @@ -731,6 +732,10 @@ void MainWindow::windowShown(void) } } + // !!! -- TEST -- !!! + ShellIntegration::install(); + // !!! -- TEST -- !!! + //Add files from the command-line for(int i = 0; i < arguments.count() - 1; i++) { diff --git a/src/ShellIntegration.cpp b/src/ShellIntegration.cpp new file mode 100644 index 00000000..f05c4548 --- /dev/null +++ b/src/ShellIntegration.cpp @@ -0,0 +1,166 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2011 LoRd_MuldeR +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +#include "ShellIntegration.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "Global.h" +#include "Registry_Decoder.h" + +//Const +static const char *g_lamexpShellAction = "ConvertWithLameXP"; +static const char *g_lamexpFileType = "LameXP.SupportedAudioFile"; + +//////////////////////////////////////////////////////////// +// Public Functions +//////////////////////////////////////////////////////////// + +void ShellIntegration::install(void) +{ + HKEY key = NULL; + + const QString lamexpFileType(g_lamexpFileType); + const QString lamexpFileInfo(tr("Audio File supported by LameXP")); + const QString lamexpShellText(tr("Convert this file with LameXP v4")); + const QString lamexpShellCommand = QString("\"%1\" --add \"%2\"").arg(QDir::toNativeSeparators(QFileInfo(QApplication::applicationFilePath()).canonicalFilePath()), "%1"); + const QString lamexpShellAction(g_lamexpShellAction); + + //Register the LameXP file type + if(RegCreateKeyEx(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Classes\\%1").arg(lamexpFileType)), NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) + { + RegSetKeyValue(key, NULL, NULL, REG_SZ, QWCHAR(lamexpFileInfo), (lamexpFileInfo.size() + 1) * sizeof(wchar_t)); + RegCloseKey(key); + } + if(RegCreateKeyEx(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Classes\\%1\\shell").arg(lamexpFileType)), NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) + { + RegSetKeyValue(key, NULL, NULL, REG_SZ, QWCHAR(lamexpShellAction), (lamexpShellAction.size() + 1) * sizeof(wchar_t)); + RegCloseKey(key); + } + + //Detect supported file types + QStringList *types = detectTypes(lamexpFileType, lamexpShellAction); + + //Add LameXP shell action to all supported file types + while(types && (!types->isEmpty())) + { + QString currentType = types->takeFirst(); + + if(RegCreateKeyEx(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Classes\\%1\\shell\\%2").arg(currentType, lamexpShellAction)), NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) + { + RegSetKeyValue(key, NULL, NULL, REG_SZ, QWCHAR(lamexpShellText), (lamexpShellText.size() + 1) * sizeof(wchar_t)); + RegCloseKey(key); + } + + if(RegCreateKeyEx(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Classes\\%1\\shell\\%2\\command").arg(currentType, lamexpShellAction)), NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) + { + RegSetKeyValue(key, NULL, NULL, REG_SZ, QWCHAR(lamexpShellCommand), (lamexpShellCommand.size() + 1) * sizeof(wchar_t)); + RegCloseKey(key); + } + } + + //Shell notification + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + + //Free + delete types; +} + +void ShellIntegration::remove(void) +{ + qDebug("Sorry, not implemented yet :-["); + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); +} + +//////////////////////////////////////////////////////////// +// Private Functions +//////////////////////////////////////////////////////////// + +QStringList *ShellIntegration::detectTypes(const QString &lamexpFileType, const QString &lamexpShellAction) +{ + HKEY key = NULL; + + QStringList *nativeTypes = new QStringList(); + QStringList supportedTypes = DecoderRegistry::getSupportedTypes(); + QStringList extensions; + + QRegExp regExp1("\\((.+)\\)"); + QRegExp regExp2("(\\.\\w+)"); + + //Find all supported file extensions + while(!supportedTypes.isEmpty()) + { + if(regExp1.lastIndexIn(supportedTypes.takeFirst()) > 0) + { + int lastIndex = 0; + while((lastIndex = regExp2.indexIn(regExp1.cap(1), lastIndex) + 1) >= 1) + { + extensions.append(regExp2.cap(1)); + } + } + } + + //Map supported extensions to native types + while(!extensions.isEmpty()) + { + QString currentExt = extensions.takeFirst(); + SHDeleteKey(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%1").arg(currentExt))); + + if(RegOpenKeyEx(HKEY_CLASSES_ROOT, QWCHAR(currentExt), NULL, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) + { + wchar_t data[256]; + DWORD dataLen = 256 * sizeof(wchar_t); + DWORD type = NULL; + + if(RegQueryValueEx(key, NULL, NULL, &type, reinterpret_cast(data), &dataLen) == ERROR_SUCCESS) + { + if((type == REG_SZ) || (type == REG_EXPAND_SZ)) + { + QString currentType = QString::fromUtf16(reinterpret_cast(data)); + if((currentType.compare(lamexpFileType, Qt::CaseInsensitive) != 0) && !nativeTypes->contains(currentType, Qt::CaseInsensitive)) + { + nativeTypes->append(currentType); + } + } + } + RegCloseKey(key); + } + else + { + if(RegCreateKeyEx(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Classes\\%1").arg(currentExt)), NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) + { + RegSetKeyValue(key, NULL, NULL, REG_SZ, QWCHAR(lamexpFileType), (lamexpFileType.size() + 1) * sizeof(wchar_t)); + RegCloseKey(key); + } + } + } + + return nativeTypes; +} diff --git a/src/ShellIntegration.h b/src/ShellIntegration.h new file mode 100644 index 00000000..c902cf23 --- /dev/null +++ b/src/ShellIntegration.h @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2011 LoRd_MuldeR +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// http://www.gnu.org/licenses/gpl-2.0.txt +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +class QString; +class QStringList; + +class ShellIntegration : public QObject +{ + Q_OBJECT + +public: + static void install(void); + static void remove(void); + +private: + static QStringList *detectTypes(const QString &lamexpFileType, const QString &lamexpShellAction); +};