Second part of LameXP shell integration. We can now remove the shell integration again. Also installing/removing the shell integration was moved into a separate thread in order to speed-up the startup.

This commit is contained in:
LoRd_MuldeR 2011-01-29 00:40:29 +01:00
parent 02abefddd7
commit 0e59d6f9a2
14 changed files with 460 additions and 161 deletions

View File

@ -677,6 +677,10 @@
<source>Encode!</source> <source>Encode!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Disable Shell Integration</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Adding file(s), please wait...</source> <source>Adding file(s), please wait...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -705,6 +709,46 @@
<source>This usually means the file is damaged or the file format is not supported.</source> <source>This usually means the file is damaged or the file format is not supported.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Downloading WMA Decoder Setup, please wait...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to download the WMA Decoder setup. Check your internet connection!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Try Again</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The download seems to be corrupted. Please try again!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WMA Decoder</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The WMA File Decoder has been installed. Please restart LameXP now!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Quit LameXP</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Postpone</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>DEMO VERSION</source> <source>DEMO VERSION</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -773,10 +817,6 @@
<source>Your did not check for LameXP updates yet. Check for updates now?</source> <source>Your did not check for LameXP updates yet. Check for updates now?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Postpone</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>LameXP detected that your version of the Nero AAC encoder is outdated!</source> <source>LameXP detected that your version of the Nero AAC encoder is outdated!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -825,10 +865,18 @@
<source>You won&apos;t be able to process WMA files as input unless the WMA File Decoder component is installed!</source> <source>You won&apos;t be able to process WMA files as input unless the WMA File Decoder component is installed!</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Do you want to download and install the WMA File Decoder component now?</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>WMA Decoder Missing</source> <source>WMA Decoder Missing</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Download &amp;&amp; Install</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>LameXP</source> <source>LameXP</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -1034,47 +1082,19 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>Do you want to download and install the WMA File Decoder component now?</source> <source>Shell Integration</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>Download &amp;&amp; Install</source> <source>Do you really want to disable the LameXP shell integration?</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>Cancel</source> <source>The LameXP shell integration has been disabled.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>Downloading WMA Decoder Setup, please wait...</source> <source>The LameXP shell integration has been re-enabled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Download Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to download the WMA Decoder setup. Check your internet connection!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Try Again</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The download seems to be corrupted. Please try again!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>WMA Decoder</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The WMA File Decoder has been installed. Please restart LameXP now!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Quit LameXP</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
@ -1443,7 +1463,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>Convert this file with LameXP v4</source> <source>Convert this file with LameXP v%1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View File

@ -672,7 +672,7 @@
</message> </message>
<message> <message>
<source>Do you really want to disable the update reminder?</source> <source>Do you really want to disable the update reminder?</source>
<translation>Wollen Sie die Update Erinnerung wirklich deaktivieren?</translation> <translation>Sind Sie sicher, dass Sie die Update-Erinnerung jetzt deaktivieren möchten?</translation>
</message> </message>
<message> <message>
<source>Update Reminder</source> <source>Update Reminder</source>
@ -684,7 +684,7 @@
</message> </message>
<message> <message>
<source>Do you really want to disable all sound effects?</source> <source>Do you really want to disable all sound effects?</source>
<translation>Wollen Sie wirklich alle Sound-Effekte deaktivieren?</translation> <translation>Sind Sie sicher, dass Sie alle Sound-Effekte deaktivieren möchten?</translation>
</message> </message>
<message> <message>
<source>Sound Effects</source> <source>Sound Effects</source>
@ -720,7 +720,7 @@
</message> </message>
<message> <message>
<source>Do you really want to disable all WMA Decoder notifications?</source> <source>Do you really want to disable all WMA Decoder notifications?</source>
<translation>Möchten Sie wirklich alle WMA Dekodierer Meldungen deaktivieren?</translation> <translation>Sind Sie sicher, dass Sie alle WMA Dekodierer Meldungen deaktivieren möchten?</translation>
</message> </message>
<message> <message>
<source>All WMA Decoder notifications have been disabled.</source> <source>All WMA Decoder notifications have been disabled.</source>
@ -1078,6 +1078,26 @@
<source>Adjust Bass (dB):</source> <source>Adjust Bass (dB):</source>
<translation>Bass-Regler (dB):</translation> <translation>Bass-Regler (dB):</translation>
</message> </message>
<message>
<source>Disable Shell Integration</source>
<translation>Shell-Integration Deaktivieren</translation>
</message>
<message>
<source>Shell Integration</source>
<translation>Shell-Integration</translation>
</message>
<message>
<source>Do you really want to disable the LameXP shell integration?</source>
<translation>Sind Sie sicher, dass Sie die LameXP Shell-Integration jetzt deaktivieren möchten?</translation>
</message>
<message>
<source>The LameXP shell integration has been disabled.</source>
<translation>Die LameXP Shell-Integration wurde deaktiviert.</translation>
</message>
<message>
<source>The LameXP shell integration has been re-enabled.</source>
<translation>Die LameXP Shell-Integration wurde wieder aktiviert.</translation>
</message>
</context> </context>
<context> <context>
<name>MetaInfo</name> <name>MetaInfo</name>
@ -1444,8 +1464,8 @@
<translation>LameXP Audio-Datei</translation> <translation>LameXP Audio-Datei</translation>
</message> </message>
<message> <message>
<source>Convert this file with LameXP v4</source> <source>Convert this file with LameXP v%1</source>
<translation>Diese Datei mit LameXP v4 umwandeln</translation> <translation>Datei mit LameXP v%1 umwandeln</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -1078,6 +1078,26 @@
<source>Adjust Bass (dB):</source> <source>Adjust Bass (dB):</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Disable Shell Integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Shell Integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you really want to disable the LameXP shell integration?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The LameXP shell integration has been disabled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The LameXP shell integration has been re-enabled.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>MetaInfo</name> <name>MetaInfo</name>
@ -1444,7 +1464,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>Convert this file with LameXP v4</source> <source>Convert this file with LameXP v%1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View File

@ -1080,6 +1080,26 @@ Votre dossier TEMP est situé ici:</translation>
<source>Adjust Bass (dB):</source> <source>Adjust Bass (dB):</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Disable Shell Integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Shell Integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you really want to disable the LameXP shell integration?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The LameXP shell integration has been disabled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The LameXP shell integration has been re-enabled.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>MetaInfo</name> <name>MetaInfo</name>
@ -1446,7 +1466,7 @@ Votre dossier TEMP est situé ici:</translation>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>Convert this file with LameXP v4</source> <source>Convert this file with LameXP v%1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View File

@ -1078,6 +1078,26 @@
<source>Adjust Bass (dB):</source> <source>Adjust Bass (dB):</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Disable Shell Integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Shell Integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Do you really want to disable the LameXP shell integration?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The LameXP shell integration has been disabled.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>The LameXP shell integration has been re-enabled.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>MetaInfo</name> <name>MetaInfo</name>
@ -1444,7 +1464,7 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>Convert this file with LameXP v4</source> <source>Convert this file with LameXP v%1</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>

View File

@ -985,7 +985,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>604</width> <width>602</width>
<height>609</height> <height>609</height>
</rect> </rect>
</property> </property>
@ -2200,6 +2200,7 @@
<addaction name="actionDisableUpdateReminder"/> <addaction name="actionDisableUpdateReminder"/>
<addaction name="actionDisableWmaDecoderNotifications"/> <addaction name="actionDisableWmaDecoderNotifications"/>
<addaction name="actionDisableNeroAacNotifications"/> <addaction name="actionDisableNeroAacNotifications"/>
<addaction name="actionDisableShellIntegration"/>
</widget> </widget>
<addaction name="menuConfiguration"/> <addaction name="menuConfiguration"/>
<addaction name="actionInstallWMADecoder"/> <addaction name="actionInstallWMADecoder"/>
@ -2439,6 +2440,14 @@
<string>Encode!</string> <string>Encode!</string>
</property> </property>
</action> </action>
<action name="actionDisableShellIntegration">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Disable Shell Integration</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
@ -2482,6 +2491,8 @@
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>

Binary file not shown.

View File

@ -25,7 +25,7 @@
#define VER_LAMEXP_MAJOR 4 #define VER_LAMEXP_MAJOR 4
#define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 0 #define VER_LAMEXP_MINOR_LO 0
#define VER_LAMEXP_BUILD 273 #define VER_LAMEXP_BUILD 276
#define VER_LAMEXP_SUFFIX Beta-2 #define VER_LAMEXP_SUFFIX Beta-2
/* /*

View File

@ -75,16 +75,6 @@
#define LINK(URL) QString("<a href=\"%1\">%2</a>").arg(URL).arg(URL) #define LINK(URL) QString("<a href=\"%1\">%2</a>").arg(URL).arg(URL)
#define TEMP_HIDE_DROPBOX(CMD) { bool __dropBoxVisible = m_dropBox->isVisible(); if(__dropBoxVisible) m_dropBox->hide(); CMD; if(__dropBoxVisible) m_dropBox->show(); } #define TEMP_HIDE_DROPBOX(CMD) { bool __dropBoxVisible = m_dropBox->isVisible(); if(__dropBoxVisible) m_dropBox->hide(); CMD; if(__dropBoxVisible) m_dropBox->show(); }
//Helper class
//class Index: public QObjectUserData
//{
//public:
// Index(int index) { m_index = index; }
// int value(void) { return m_index; }
//private:
// int m_index;
//};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Constructor // Constructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -304,11 +294,14 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
actionDisableSounds->setChecked(!m_settings->soundsEnabled()); actionDisableSounds->setChecked(!m_settings->soundsEnabled());
actionDisableNeroAacNotifications->setChecked(!m_settings->neroAacNotificationsEnabled()); actionDisableNeroAacNotifications->setChecked(!m_settings->neroAacNotificationsEnabled());
actionDisableWmaDecoderNotifications->setChecked(!m_settings->wmaDecoderNotificationsEnabled()); actionDisableWmaDecoderNotifications->setChecked(!m_settings->wmaDecoderNotificationsEnabled());
actionDisableShellIntegration->setChecked(!m_settings->shellIntegrationEnabled());
actionDisableShellIntegration->setVisible(!lamexp_portable_mode());
connect(actionDisableUpdateReminder, SIGNAL(triggered(bool)), this, SLOT(disableUpdateReminderActionTriggered(bool))); connect(actionDisableUpdateReminder, SIGNAL(triggered(bool)), this, SLOT(disableUpdateReminderActionTriggered(bool)));
connect(actionDisableSounds, SIGNAL(triggered(bool)), this, SLOT(disableSoundsActionTriggered(bool))); connect(actionDisableSounds, SIGNAL(triggered(bool)), this, SLOT(disableSoundsActionTriggered(bool)));
connect(actionInstallWMADecoder, SIGNAL(triggered(bool)), this, SLOT(installWMADecoderActionTriggered(bool))); connect(actionInstallWMADecoder, SIGNAL(triggered(bool)), this, SLOT(installWMADecoderActionTriggered(bool)));
connect(actionDisableNeroAacNotifications, SIGNAL(triggered(bool)), this, SLOT(disableNeroAacNotificationsActionTriggered(bool))); connect(actionDisableNeroAacNotifications, SIGNAL(triggered(bool)), this, SLOT(disableNeroAacNotificationsActionTriggered(bool)));
connect(actionDisableWmaDecoderNotifications, SIGNAL(triggered(bool)), this, SLOT(disableWmaDecoderNotificationsActionTriggered(bool))); connect(actionDisableWmaDecoderNotifications, SIGNAL(triggered(bool)), this, SLOT(disableWmaDecoderNotificationsActionTriggered(bool)));
connect(actionDisableShellIntegration, SIGNAL(triggered(bool)), this, SLOT(disableShellIntegrationActionTriggered(bool)));
connect(actionShowDropBoxWidget, SIGNAL(triggered(bool)), this, SLOT(showDropBoxWidgetActionTriggered(bool))); connect(actionShowDropBoxWidget, SIGNAL(triggered(bool)), this, SLOT(showDropBoxWidgetActionTriggered(bool)));
//Activate help menu actions //Activate help menu actions
@ -395,7 +388,6 @@ MainWindow::~MainWindow(void)
LAMEXP_DELETE(m_encoderButtonGroup); LAMEXP_DELETE(m_encoderButtonGroup);
LAMEXP_DELETE(m_sourceFilesContextMenu); LAMEXP_DELETE(m_sourceFilesContextMenu);
LAMEXP_DELETE(m_dropBox); LAMEXP_DELETE(m_dropBox);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -434,6 +426,81 @@ void MainWindow::addFiles(const QStringList &files)
m_banner->close(); m_banner->close();
} }
/*
* Download and install WMA Decoder component
*/
void MainWindow::installWMADecoder(void)
{
static const char *download_url = "http://www.nch.com.au/components/wmawav.exe";
static const char *download_hash = "52a3b0e6690faf3f830c336d3c0eadfb7a4e9bc6";
QString binaryWGet = lamexp_lookup_tool("wget.exe");
QString binaryElevator = lamexp_lookup_tool("elevator.exe");
if(binaryWGet.isEmpty() || binaryElevator.isEmpty())
{
throw "Required binary is not available!";
}
while(true)
{
QString setupFile = QString("%1/%2.exe").arg(lamexp_temp_folder(), lamexp_rand_str());
QProcess process;
process.setWorkingDirectory(QFileInfo(setupFile).absolutePath());
QEventLoop loop;
connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()));
connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
process.start(binaryWGet, QStringList() << "-O" << QFileInfo(setupFile).fileName() << download_url);
m_banner->show(tr("Downloading WMA Decoder Setup, please wait..."), &loop);
if(process.exitCode() != 0 || QFileInfo(setupFile).size() < 10240)
{
QFile::remove(setupFile);
if(QMessageBox::critical(this, tr("Download Failed"), tr("Failed to download the WMA Decoder setup. Check your internet connection!"), tr("Try Again"), tr("Cancel")) == 0)
{
continue;
}
return;
}
QFile setupFileContent(setupFile);
QCryptographicHash setupFileHash(QCryptographicHash::Sha1);
setupFileContent.open(QIODevice::ReadOnly);
if(setupFileContent.isOpen() && setupFileContent.isReadable())
{
setupFileHash.addData(setupFileContent.readAll());
setupFileContent.close();
}
if(_stricmp(setupFileHash.result().toHex().constData(), download_hash))
{
qWarning("Hash miscompare:\n Expected %s\n Detected %s\n", download_hash, setupFileHash.result().toHex().constData());
QFile::remove(setupFile);
if(QMessageBox::critical(this, tr("Download Failed"), tr("The download seems to be corrupted. Please try again!"), tr("Try Again"), tr("Cancel")) == 0)
{
continue;
}
return;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
process.start(binaryElevator, QStringList() << QString("/exec=%1").arg(setupFile));
loop.exec(QEventLoop::ExcludeUserInputEvents);
QFile::remove(setupFile);
QApplication::restoreOverrideCursor();
if(QMessageBox::information(this, tr("WMA Decoder"), tr("The WMA File Decoder has been installed. Please restart LameXP now!"), tr("Quit LameXP"), tr("Postpone")) == 0)
{
QApplication::quit();
}
break;
}
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// EVENTS // EVENTS
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -500,6 +567,11 @@ void MainWindow::changeEvent(QEvent *e)
m_metaInfoModel->clearData(); m_metaInfoModel->clearData();
updateEncoder(m_settings->compressionEncoder()); updateEncoder(m_settings->compressionEncoder());
updateLameAlgoQuality(sliderLameAlgoQuality->value()); updateLameAlgoQuality(sliderLameAlgoQuality->value());
if(m_settings->shellIntegrationEnabled())
{
ShellIntegration::install();
}
} }
} }
@ -726,15 +798,14 @@ void MainWindow::windowShown(void)
{ {
QString messageText; QString messageText;
messageText += QString("<nobr>%1<br>").arg(tr("LameXP has detected that the WMA File Decoder component is not currently installed on your system.")); messageText += QString("<nobr>%1<br>").arg(tr("LameXP has detected that the WMA File Decoder component is not currently installed on your system."));
messageText += QString("%1</nobr>").arg(tr("You won't be able to process WMA files as input unless the WMA File Decoder component is installed!")); messageText += QString("%1<br><br>").arg(tr("You won't be able to process WMA files as input unless the WMA File Decoder component is installed!"));
QMessageBox::information(this, tr("WMA Decoder Missing"), messageText); messageText += QString("%1</nobr>").arg(tr("Do you want to download and install the WMA File Decoder component now?"));
installWMADecoderActionTriggered(rand() % 2); if(QMessageBox::information(this, tr("WMA Decoder Missing"), messageText, tr("Download && Install"), tr("Postpone")) == 0)
{
installWMADecoder();
}
} }
} }
// !!! -- TEST -- !!!
ShellIntegration::install();
// !!! -- TEST -- !!!
//Add files from the command-line //Add files from the command-line
for(int i = 0; i < arguments.count() - 1; i++) for(int i = 0; i < arguments.count() - 1; i++)
@ -753,6 +824,12 @@ void MainWindow::windowShown(void)
m_delayedFileTimer->start(5000); m_delayedFileTimer->start(5000);
} }
//Enable shell integration
if(m_settings->shellIntegrationEnabled())
{
ShellIntegration::install();
}
//Make DropBox visible //Make DropBox visible
if(m_settings->dropBoxWidgetEnabled()) if(m_settings->dropBoxWidgetEnabled())
{ {
@ -2040,81 +2117,15 @@ void MainWindow::disableWmaDecoderNotificationsActionTriggered(bool checked)
*/ */
void MainWindow::installWMADecoderActionTriggered(bool checked) void MainWindow::installWMADecoderActionTriggered(bool checked)
{ {
static const char *download_url = "http://www.nch.com.au/components/wmawav.exe"; if(QMessageBox::question(this, tr("Install WMA Decoder"), tr("Do you want to download and install the WMA File Decoder component now?"), tr("Download && Install"), tr("Cancel")) == 0)
static const char *download_hash = "52a3b0e6690faf3f830c336d3c0eadfb7a4e9bc6";
if(QMessageBox::question(this, tr("Install WMA Decoder"), tr("Do you want to download and install the WMA File Decoder component now?"), tr("Download && Install"), tr("Cancel")) != 0)
{ {
return; installWMADecoder();
}
QString binaryWGet = lamexp_lookup_tool("wget.exe");
QString binaryElevator = lamexp_lookup_tool("elevator.exe");
if(binaryWGet.isEmpty() || binaryElevator.isEmpty())
{
throw "Required binary is not available!";
}
while(true)
{
QString setupFile = QString("%1/%2.exe").arg(lamexp_temp_folder(), lamexp_rand_str());
QProcess process;
process.setWorkingDirectory(QFileInfo(setupFile).absolutePath());
QEventLoop loop;
connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()));
connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
process.start(binaryWGet, QStringList() << "-O" << QFileInfo(setupFile).fileName() << download_url);
m_banner->show(tr("Downloading WMA Decoder Setup, please wait..."), &loop);
if(process.exitCode() != 0 || QFileInfo(setupFile).size() < 10240)
{
QFile::remove(setupFile);
if(QMessageBox::critical(this, tr("Download Failed"), tr("Failed to download the WMA Decoder setup. Check your internet connection!"), tr("Try Again"), tr("Cancel")) == 0)
{
continue;
}
return;
}
QFile setupFileContent(setupFile);
QCryptographicHash setupFileHash(QCryptographicHash::Sha1);
setupFileContent.open(QIODevice::ReadOnly);
if(setupFileContent.isOpen() && setupFileContent.isReadable())
{
setupFileHash.addData(setupFileContent.readAll());
setupFileContent.close();
}
if(_stricmp(setupFileHash.result().toHex().constData(), download_hash))
{
qWarning("Hash miscompare:\n Expected %s\n Detected %s\n", download_hash, setupFileHash.result().toHex().constData());
QFile::remove(setupFile);
if(QMessageBox::critical(this, tr("Download Failed"), tr("The download seems to be corrupted. Please try again!"), tr("Try Again"), tr("Cancel")) == 0)
{
continue;
}
return;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
process.start(binaryElevator, QStringList() << QString("/exec=%1").arg(setupFile));
loop.exec(QEventLoop::ExcludeUserInputEvents);
QFile::remove(setupFile);
QApplication::restoreOverrideCursor();
if(QMessageBox::information(this, tr("WMA Decoder"), tr("The WMA File Decoder has been installed. Please restart LameXP now!"), tr("Quit LameXP"), tr("Postpone")) == 0)
{
QApplication::quit();
}
break;
} }
} }
/*
* Show the "drop box" widget
*/
void MainWindow::showDropBoxWidgetActionTriggered(bool checked) void MainWindow::showDropBoxWidgetActionTriggered(bool checked)
{ {
m_settings->dropBoxWidgetEnabled(true); m_settings->dropBoxWidgetEnabled(true);
@ -2126,3 +2137,31 @@ void MainWindow::showDropBoxWidgetActionTriggered(bool checked)
FLASH_WINDOW(m_dropBox); FLASH_WINDOW(m_dropBox);
} }
/*
* Disable shell integration action
*/
void MainWindow::disableShellIntegrationActionTriggered(bool checked)
{
if(checked)
{
if(0 == QMessageBox::question(this, tr("Shell Integration"), tr("Do you really want to disable the LameXP shell integration?"), tr("Yes"), tr("No"), QString(), 1))
{
ShellIntegration::remove();
QMessageBox::information(this, tr("Shell Integration"), tr("The LameXP shell integration has been disabled."));
m_settings->shellIntegrationEnabled(false);
}
else
{
m_settings->shellIntegrationEnabled(true);
}
}
else
{
ShellIntegration::install();
QMessageBox::information(this, tr("Shell Integration"), tr("The LameXP shell integration has been re-enabled."));
m_settings->shellIntegrationEnabled(true);
}
actionDisableShellIntegration->setChecked(!m_settings->shellIntegrationEnabled());
}

View File

@ -110,6 +110,7 @@ private slots:
void disableNeroAacNotificationsActionTriggered(bool checked); void disableNeroAacNotificationsActionTriggered(bool checked);
void disableWmaDecoderNotificationsActionTriggered(bool checked); void disableWmaDecoderNotificationsActionTriggered(bool checked);
void showDropBoxWidgetActionTriggered(bool checked); void showDropBoxWidgetActionTriggered(bool checked);
void disableShellIntegrationActionTriggered(bool);
protected: protected:
void showEvent(QShowEvent *event); void showEvent(QShowEvent *event);
@ -122,6 +123,7 @@ protected:
private: private:
void addFiles(const QStringList &files); void addFiles(const QStringList &files);
void installWMADecoder(void);
bool m_accepted; bool m_accepted;
bool m_firstTimeShown; bool m_firstTimeShown;

View File

@ -50,6 +50,7 @@ static const char *g_settingsId_soundsEnabled = "Flags/EnableSounds";
static const char *g_settingsId_neroAacNotificationsEnabled = "Flags/EnableNeroAacNotifications"; static const char *g_settingsId_neroAacNotificationsEnabled = "Flags/EnableNeroAacNotifications";
static const char *g_settingsId_wmaDecoderNotificationsEnabled = "Flags/EnableWmaDecoderNotifications"; static const char *g_settingsId_wmaDecoderNotificationsEnabled = "Flags/EnableWmaDecoderNotifications";
static const char *g_settingsId_dropBoxWidgetEnabled = "Flags/EnableDropBoxWidget"; static const char *g_settingsId_dropBoxWidgetEnabled = "Flags/EnableDropBoxWidget";
static const char *g_settingsId_shellIntegrationEnabled = "Flags/EnableShellIntegration";
static const char *g_settingsId_currentLanguage = "Localization/Language"; static const char *g_settingsId_currentLanguage = "Localization/Language";
static const char *g_settingsId_lameAlgoQuality = "AdvancedOptions/LAME/AlgorithmQuality"; static const char *g_settingsId_lameAlgoQuality = "AdvancedOptions/LAME/AlgorithmQuality";
static const char *g_settingsId_lameChannelMode = "AdvancedOptions/LAME/ChannelMode"; static const char *g_settingsId_lameChannelMode = "AdvancedOptions/LAME/ChannelMode";
@ -218,7 +219,8 @@ MAKE_OPTION3(soundsEnabled, true)
MAKE_OPTION3(neroAacNotificationsEnabled, true) MAKE_OPTION3(neroAacNotificationsEnabled, true)
MAKE_OPTION3(wmaDecoderNotificationsEnabled, true) MAKE_OPTION3(wmaDecoderNotificationsEnabled, true)
MAKE_OPTION3(dropBoxWidgetEnabled, true) MAKE_OPTION3(dropBoxWidgetEnabled, true)
MAKE_OPTION2(currentLanguage, defaultLanguage()); MAKE_OPTION3(shellIntegrationEnabled, !lamexp_portable_mode())
MAKE_OPTION2(currentLanguage, defaultLanguage())
MAKE_OPTION1(lameAlgoQuality, 3) MAKE_OPTION1(lameAlgoQuality, 3)
MAKE_OPTION1(lameChannelMode, 0); MAKE_OPTION1(lameChannelMode, 0);
MAKE_OPTION3(bitrateManagementEnabled, false) MAKE_OPTION3(bitrateManagementEnabled, false)

View File

@ -79,22 +79,23 @@ public:
MAKE_OPTION_DEC2(autoUpdateLastCheck); MAKE_OPTION_DEC2(autoUpdateLastCheck);
MAKE_OPTION_DEC3(autoUpdateEnabled); MAKE_OPTION_DEC3(autoUpdateEnabled);
MAKE_OPTION_DEC3(soundsEnabled); MAKE_OPTION_DEC3(soundsEnabled);
MAKE_OPTION_DEC3(neroAacNotificationsEnabled) MAKE_OPTION_DEC3(neroAacNotificationsEnabled);
MAKE_OPTION_DEC3(wmaDecoderNotificationsEnabled) MAKE_OPTION_DEC3(wmaDecoderNotificationsEnabled);
MAKE_OPTION_DEC3(dropBoxWidgetEnabled) MAKE_OPTION_DEC3(dropBoxWidgetEnabled);
MAKE_OPTION_DEC3(shellIntegrationEnabled);
MAKE_OPTION_DEC2(currentLanguage); MAKE_OPTION_DEC2(currentLanguage);
MAKE_OPTION_DEC1(lameAlgoQuality); MAKE_OPTION_DEC1(lameAlgoQuality);
MAKE_OPTION_DEC1(lameChannelMode); MAKE_OPTION_DEC1(lameChannelMode);
MAKE_OPTION_DEC3(bitrateManagementEnabled); MAKE_OPTION_DEC3(bitrateManagementEnabled);
MAKE_OPTION_DEC1(bitrateManagementMinRate); MAKE_OPTION_DEC1(bitrateManagementMinRate);
MAKE_OPTION_DEC1(bitrateManagementMaxRate); MAKE_OPTION_DEC1(bitrateManagementMaxRate);
MAKE_OPTION_DEC1(samplingRate) MAKE_OPTION_DEC1(samplingRate);
MAKE_OPTION_DEC3(neroAACEnable2Pass) MAKE_OPTION_DEC3(neroAACEnable2Pass);
MAKE_OPTION_DEC1(neroAACProfile) MAKE_OPTION_DEC1(neroAACProfile);
MAKE_OPTION_DEC3(normalizationFilterEnabled) MAKE_OPTION_DEC3(normalizationFilterEnabled);
MAKE_OPTION_DEC1(normalizationFilterMaxVolume) MAKE_OPTION_DEC1(normalizationFilterMaxVolume);
MAKE_OPTION_DEC1(toneAdjustBass) MAKE_OPTION_DEC1(toneAdjustBass);
MAKE_OPTION_DEC1(toneAdjustTreble) MAKE_OPTION_DEC1(toneAdjustTreble);
//Misc //Misc
void validate(void); void validate(void);

View File

@ -27,6 +27,7 @@
#include <QApplication> #include <QApplication>
#include <QFileInfo> #include <QFileInfo>
#include <QDir> #include <QDir>
#include <QMutexLocker>
#include <Windows.h> #include <Windows.h>
#include <Shlobj.h> #include <Shlobj.h>
@ -39,29 +40,74 @@
static const char *g_lamexpShellAction = "ConvertWithLameXP"; static const char *g_lamexpShellAction = "ConvertWithLameXP";
static const char *g_lamexpFileType = "LameXP.SupportedAudioFile"; static const char *g_lamexpFileType = "LameXP.SupportedAudioFile";
//Mutex
QMutex ShellIntegration::m_mutex;
//Macros
#define REG_WRITE_STRING(KEY, STR) RegSetKeyValue(key, NULL, NULL, REG_SZ, QWCHAR(STR), (STR.size() + 1) * sizeof(wchar_t))
////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////
ShellIntegration::ShellIntegration(bool install)
:
QThread(),
m_install(install)
{
}
ShellIntegration::~ShellIntegration(void)
{
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Public Functions // Public Functions
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void ShellIntegration::install(void) void ShellIntegration::install(bool async)
{ {
//Install asynchronously
if(async)
{
ShellIntegration *shellIntegration = new ShellIntegration(true);
connect(shellIntegration, SIGNAL(finished()), shellIntegration, SLOT(deleteLater()));
shellIntegration->start();
return;
}
//Serialize
QMutexLocker lock(&m_mutex);
//Registry key
HKEY key = NULL; HKEY key = NULL;
//Init some consts
const QString lamexpFileType(g_lamexpFileType); const QString lamexpFileType(g_lamexpFileType);
const QString lamexpFileInfo(tr("Audio File supported by LameXP")); const QString lamexpFileInfo(tr("Audio File supported by LameXP"));
const QString lamexpShellText(tr("Convert this file with LameXP v4")); const QString lamexpShellText(tr("Convert this file with LameXP v%1").arg(QString().sprintf("%d.%02d", lamexp_version_major(), lamexp_version_minor())));
const QString lamexpShellCommand = QString("\"%1\" --add \"%2\"").arg(QDir::toNativeSeparators(QFileInfo(QApplication::applicationFilePath()).canonicalFilePath()), "%1"); const QString lamexpShellCommand = QString("\"%1\" --add \"%2\"").arg(QDir::toNativeSeparators(QFileInfo(QApplication::applicationFilePath()).canonicalFilePath()), "%1");
const QString lamexpShellAction(g_lamexpShellAction); const QString lamexpShellAction(g_lamexpShellAction);
//Register the LameXP file type //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) 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)); REG_WRITE_STRING(key, lamexpFileInfo);
RegCloseKey(key); 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) 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)); REG_WRITE_STRING(key, lamexpShellAction);
RegCloseKey(key);
}
if(RegCreateKeyEx(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Classes\\%1\\shell\\%2").arg(lamexpFileType, lamexpShellAction)), NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS)
{
REG_WRITE_STRING(key, lamexpShellText);
RegCloseKey(key);
}
if(RegCreateKeyEx(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Classes\\%1\\shell\\%2\\command").arg(lamexpFileType, lamexpShellAction)), NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS)
{
REG_WRITE_STRING(key, lamexpShellCommand);
RegCloseKey(key); RegCloseKey(key);
} }
@ -75,13 +121,13 @@ void ShellIntegration::install(void)
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) 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)); REG_WRITE_STRING(key, lamexpShellText);
RegCloseKey(key); 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) 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)); REG_WRITE_STRING(key, lamexpShellCommand);
RegCloseKey(key); RegCloseKey(key);
} }
} }
@ -93,9 +139,55 @@ void ShellIntegration::install(void)
delete types; delete types;
} }
void ShellIntegration::remove(void) void ShellIntegration::remove(bool async)
{ {
qDebug("Sorry, not implemented yet :-["); //Remove asynchronously
if(async)
{
ShellIntegration *shellIntegration = new ShellIntegration(false);
connect(shellIntegration, SIGNAL(finished()), shellIntegration, SLOT(deleteLater()));
shellIntegration->start();
return;
}
//Serialize
QMutexLocker lock(&m_mutex);
//Init some consts
const QString lamexpFileType(g_lamexpFileType);
const QString lamexpShellAction(g_lamexpShellAction);
//Initialization
HKEY key = NULL;
QStringList fileTypes;
//Find all registered file types
if(RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Classes", NULL, KEY_ENUMERATE_SUB_KEYS ,&key) == ERROR_SUCCESS)
{
wchar_t name[256];
for(DWORD i = 0; true; i++)
{
DWORD size = 256;
if(RegEnumKeyEx(key, i, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
fileTypes << QString::fromUtf16(reinterpret_cast<const unsigned short*>(name));
continue;
}
break;
}
}
//Remove shell action from all file types
while(!fileTypes.isEmpty())
{
SHDeleteKey(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Classes\\%1\\shell\\%2").arg(fileTypes.takeFirst(), lamexpShellAction)));
}
//Unregister LameXP file type
SHDeleteKey(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Classes\\%1").arg(lamexpFileType)));
//Shell notification
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
} }
@ -131,7 +223,6 @@ QStringList *ShellIntegration::detectTypes(const QString &lamexpFileType, const
while(!extensions.isEmpty()) while(!extensions.isEmpty())
{ {
QString currentExt = extensions.takeFirst(); 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) if(RegOpenKeyEx(HKEY_CLASSES_ROOT, QWCHAR(currentExt), NULL, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{ {
@ -160,6 +251,46 @@ QStringList *ShellIntegration::detectTypes(const QString &lamexpFileType, const
RegCloseKey(key); RegCloseKey(key);
} }
} }
if(RegOpenKeyEx(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%1\\UserChoice").arg(currentExt)), NULL, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{
wchar_t data[256];
DWORD dataLen = 256 * sizeof(wchar_t);
DWORD type = NULL;
if(RegQueryValueEx(key, L"Progid", NULL, &type, reinterpret_cast<BYTE*>(data), &dataLen) == ERROR_SUCCESS)
{
if((type == REG_SZ) || (type == REG_EXPAND_SZ))
{
QString currentType = QString::fromUtf16(reinterpret_cast<unsigned short*>(data));
if((currentType.compare(lamexpFileType, Qt::CaseInsensitive) != 0) && !nativeTypes->contains(currentType, Qt::CaseInsensitive))
{
nativeTypes->append(currentType);
}
}
}
RegCloseKey(key);
}
if(RegOpenKeyEx(HKEY_CURRENT_USER, QWCHAR(QString("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%1\\OpenWithProgids").arg(currentExt)), NULL, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{
wchar_t name[256];
for(DWORD i = 0; true; i++)
{
DWORD size = 256;
if(RegEnumValue(key, i, name, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
QString currentType = QString::fromUtf16(reinterpret_cast<unsigned short*>(name));
if((currentType.compare(lamexpFileType, Qt::CaseInsensitive) != 0) && !nativeTypes->contains(currentType, Qt::CaseInsensitive))
{
nativeTypes->append(currentType);
}
continue;
}
break;
}
RegCloseKey(key);
}
} }
return nativeTypes; return nativeTypes;

View File

@ -21,19 +21,32 @@
#pragma once #pragma once
#include <QObject> #include <QThread>
#include <QMutex>
class QString; class QString;
class QStringList; class QStringList;
class ShellIntegration : public QObject class ShellIntegration : public QThread
{ {
Q_OBJECT Q_OBJECT
public: public:
static void install(void); static void install(bool async = true);
static void remove(void); static void remove(bool async = true);
protected:
void run()
{
if(m_install) install(false); else remove(false);
}
private: private:
ShellIntegration(bool install = true);
~ShellIntegration(void);
static QStringList *detectTypes(const QString &lamexpFileType, const QString &lamexpShellAction); static QStringList *detectTypes(const QString &lamexpFileType, const QString &lamexpShellAction);
static QMutex m_mutex;
bool m_install;
}; };