diff --git a/LameXP.vcproj b/LameXP.vcproj index d959f717..ee432ab4 100644 --- a/LameXP.vcproj +++ b/LameXP.vcproj @@ -306,6 +306,10 @@ RelativePath=".\src\Decoder_Vorbis.cpp" > + + @@ -482,6 +486,10 @@ RelativePath=".\src\Decoder_Vorbis.h" > + + diff --git a/etc/NSIS/setup.nsi b/etc/NSIS/setup.nsi index c3c1eb43..5f34f1c5 100644 --- a/etc/NSIS/setup.nsi +++ b/etc/NSIS/setup.nsi @@ -118,6 +118,9 @@ VIAddVersionKey "Website" "http://mulder.at.gg/" !define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM !define MUI_STARTMENUPAGE_REGISTRY_KEY "${MyRegPath}" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "StartmenuFolder" +!define MUI_LANGDLL_REGISTRY_ROOT HKLM +!define MUI_LANGDLL_REGISTRY_KEY "${MyRegPath}" +!define MUI_LANGDLL_REGISTRY_VALUENAME "SetupLanguage" !define MUI_STARTMENUPAGE_DEFAULTFOLDER "LameXP v${LAMEXP_VERSION}" !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_UNFINISHPAGE_NOAUTOCLOSE @@ -373,11 +376,17 @@ SectionEnd Section "Uninstall" !insertmacro PrintProgress "$(LAMEXP_LANG_STATUS_UNINSTALL)" + IfFileExists "$INSTDIR\LameXP.exe" 0 UnNotInstalled + !insertmacro PrintProgress "$(LAMEXP_LANG_STATUS_CLOSING)" + !insertmacro UAC_AsUser_Call Function un.CloseRunningInstance UAC_SYNCOUTDIR + UnNotInstalled: + Delete /REBOOTOK "$INSTDIR\*.exe" Delete /REBOOTOK "$INSTDIR\*.txt" RMDir "$INSTDIR" !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder + StrCmp "$StartMenuFolder" "" NoStartmenuFolder IfFileExists "$SMPROGRAMS\$StartMenuFolder\*.*" 0 NoStartmenuFolder Delete /REBOOTOK "$SMPROGRAMS\$StartMenuFolder\*.lnk" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuFolder\*.url" @@ -389,6 +398,7 @@ Section "Uninstall" DeleteRegValue HKLM "${MyRegPath}" "UninstallString" DeleteRegValue HKLM "${MyRegPath}" "DisplayName" DeleteRegValue HKLM "${MyRegPath}" "StartmenuFolder" + DeleteRegValue HKLM "${MyRegPath}" "SetupLanguage" !insertmacro PrintProgress "$(MUI_UNTEXT_FINISH_TITLE)." SectionEnd @@ -437,3 +447,8 @@ FunctionEnd Function CloseRunningInstance nsExec::Exec /TIMEOUT=30000 '"$OUTDIR\LameXP.exe" --force-kill' FunctionEnd + +Function un.CloseRunningInstance + nsExec::Exec /TIMEOUT=30000 '"$OUTDIR\LameXP.exe" --force-kill' +FunctionEnd + diff --git a/res/Icons.qrc b/res/Icons.qrc index 716ddfe8..6fccecd4 100644 --- a/res/Icons.qrc +++ b/res/Icons.qrc @@ -17,7 +17,9 @@ icons/calendar.png icons/cancel.png icons/cd.png + icons/cd_add.png icons/cd_burn.png + icons/cd_delete.png icons/cd_edit.png icons/cd_go.png icons/clock_play.png diff --git a/src/Config.h b/src/Config.h index a7455353..f8063dbd 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 145 +#define VER_LAMEXP_BUILD 147 #define VER_LAMEXP_SUFFIX TechPreview /* diff --git a/src/Decoder_Abstract.cpp b/src/Decoder_Abstract.cpp index 685d2e6f..c6c5dd52 100644 --- a/src/Decoder_Abstract.cpp +++ b/src/Decoder_Abstract.cpp @@ -37,3 +37,8 @@ bool AbstractDecoder::isFormatSupported(const QString &containerType, const QStr { return false; } + +bool AbstractDecoder::isDecoderAvailable(void) +{ + return true; +} diff --git a/src/Decoder_Abstract.h b/src/Decoder_Abstract.h index 581114b5..0726972b 100644 --- a/src/Decoder_Abstract.h +++ b/src/Decoder_Abstract.h @@ -34,4 +34,6 @@ public: //Internal decoder API virtual bool decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag) = 0; static bool isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion); + static bool isDecoderAvailable(void); }; + diff --git a/src/Decoder_WMA.cpp b/src/Decoder_WMA.cpp new file mode 100644 index 00000000..b2fc93f0 --- /dev/null +++ b/src/Decoder_WMA.cpp @@ -0,0 +1,139 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2010 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 "Decoder_WMA.h" + +#include "Global.h" + +#include +#include +#include +#include +#include + +WMADecoder::WMADecoder(void) +: + m_binary(lamexp_lookup_tool("wmawav.exe")), + m_semaphore(new QSystemSemaphore("{84BB780D-67D3-49DC-ADF0-97C795A55D5C}", 1)) +{ + if(m_binary.isEmpty()) + { + throw "Error initializing WMA decoder. Tool 'wmawav.exe' is not registred!"; + } +} + +WMADecoder::~WMADecoder(void) +{ +} + +bool WMADecoder::decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag) +{ + QProcess process; + QStringList args; + + args << pathToShort(QDir::toNativeSeparators(sourceFile)); + args << pathToShort(QDir::toNativeSeparators(outputFile)); + + if(!m_semaphore->acquire()) + { + emit messageLogged("Failed to acquire the semaphore!"); + return false; + } + + if(!startProcess(process, m_binary, args)) + { + m_semaphore->release(); + return false; + } + + bool bTimeout = false; + bool bAborted = false; + + //The WMA Decoder doesn't actually send any status updates :-[ + emit statusUpdated(20 + (QUuid::createUuid().data1 % 80)); + + while(process.state() != QProcess::NotRunning) + { + if(*abortFlag) + { + process.kill(); + bAborted = true; + emit messageLogged("\nABORTED BY USER !!!"); + break; + } + process.waitForReadyRead(); + if(!process.bytesAvailable() && process.state() == QProcess::Running) + { + process.kill(); + qWarning("WmaWav process timed out <-- killing!"); + bTimeout = true; + break; + } + while(process.bytesAvailable() > 0) + { + QByteArray line = process.readLine(); + QString text = QString::fromUtf8(line.constData()).simplified(); + if(!text.isEmpty()) + { + emit messageLogged(text); + } + } + } + + process.waitForFinished(); + if(process.state() != QProcess::NotRunning) + { + process.kill(); + process.waitForFinished(-1); + } + + emit statusUpdated(100); + emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode())); + m_semaphore->release(); + + if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit || QFileInfo(outputFile).size() == 0) + { + return false; + } + + return true; +} + +bool WMADecoder::isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion) +{ + if(containerType.compare("Windows Media", Qt::CaseInsensitive) == 0) + { + if(formatType.compare("WMA", Qt::CaseInsensitive) == 0) + { + if(formatVersion.compare("Version 1", Qt::CaseInsensitive) == 0 || formatVersion.compare("Version 2", Qt::CaseInsensitive) == 0 || formatVersion.compare("Version 3", Qt::CaseInsensitive) == 0 || formatProfile.compare("Pro", Qt::CaseInsensitive) == 0 || formatProfile.compare("Lossless", Qt::CaseInsensitive) == 0) + { + return true; + } + } + } + + return false; +} + +bool WMADecoder::isDecoderAvailable(void) +{ + return lamexp_check_tool("wmawav.exe"); +} diff --git a/src/Decoder_WMA.h b/src/Decoder_WMA.h new file mode 100644 index 00000000..475dae1d --- /dev/null +++ b/src/Decoder_WMA.h @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2010 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 "Decoder_Abstract.h" + +class QSystemSemaphore; + +class WMADecoder : public AbstractDecoder +{ +public: + WMADecoder(void); + ~WMADecoder(void); + + virtual bool decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag); + static bool isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion); + static bool isDecoderAvailable(void); + +private: + const QString m_binary; + QSystemSemaphore *m_semaphore; +}; diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp index 2a0e99c7..1a015b48 100644 --- a/src/Dialog_MainWindow.cpp +++ b/src/Dialog_MainWindow.cpp @@ -1481,7 +1481,10 @@ void MainWindow::installWMADecoderActionTriggered(bool checked) QFile::remove(setupFile); QApplication::restoreOverrideCursor(); - QMessageBox::information(this, "WMA Decoder", "The WMA File Decoder has been installed. Please restart LameXP now!"); + if(QMessageBox::information(this, "WMA Decoder", "The WMA File Decoder has been installed. Please restart LameXP now!", "Quit LameXP", "Ignore") == 0) + { + QApplication::quit(); + } break; } } diff --git a/src/Dialog_Processing.cpp b/src/Dialog_Processing.cpp index d7e8775d..83dc226c 100644 --- a/src/Dialog_Processing.cpp +++ b/src/Dialog_Processing.cpp @@ -70,7 +70,7 @@ ProcessingDialog::ProcessingDialog(FileListModel *fileListModel, AudioFileModel *metaInfo, SettingsModel *settings, QWidget *parent) : QDialog(parent), - m_systemTray(new QSystemTrayIcon(QIcon(":/icons/cd.png"), this)), + m_systemTray(new QSystemTrayIcon(QIcon(":/icons/cd_go.png"), this)), m_settings(settings), m_metaInfo(metaInfo) { @@ -318,6 +318,7 @@ void ProcessingDialog::doneEncoding(void) WinSevenTaskbar::setOverlayIcon(this, &QIcon(":/icons/error.png")); SET_PROGRESS_TEXT((m_succeededJobs.count() > 0) ? QString("Process was aborted by the user after %1 file(s)!").arg(QString::number(m_succeededJobs.count())) : "Process was aborted prematurely by the user!"); m_systemTray->showMessage("LameXP - Aborted", "Process was aborted by the user.", QSystemTrayIcon::Warning); + m_systemTray->setIcon(QIcon(":/icons/cd_delete.png")); QApplication::processEvents(); if(m_settings->soundsEnabled()) PlaySound(MAKEINTRESOURCE(IDR_WAVE_ABORTED), GetModuleHandle(NULL), SND_RESOURCE | SND_SYNC); } @@ -329,7 +330,8 @@ void ProcessingDialog::doneEncoding(void) WinSevenTaskbar::setTaskbarState(this, WinSevenTaskbar::WinSevenTaskbarErrorState); WinSevenTaskbar::setOverlayIcon(this, &QIcon(":/icons/exclamation.png")); SET_PROGRESS_TEXT(QString("Error: %1 of %2 files failed. Double-click failed items for detailed information!").arg(QString::number(m_failedJobs.count()), QString::number(m_failedJobs.count() + m_succeededJobs.count()))); - m_systemTray->showMessage("LameXP - Error", "At least one file has failed!", QSystemTrayIcon::Critical ); + m_systemTray->showMessage("LameXP - Error", "At least one file has failed!", QSystemTrayIcon::Critical); + m_systemTray->setIcon(QIcon(":/icons/cd_delete.png")); QApplication::processEvents(); if(m_settings->soundsEnabled()) PlaySound(MAKEINTRESOURCE(IDR_WAVE_ERROR), GetModuleHandle(NULL), SND_RESOURCE | SND_SYNC); } @@ -340,6 +342,7 @@ void ProcessingDialog::doneEncoding(void) WinSevenTaskbar::setOverlayIcon(this, &QIcon(":/icons/accept.png")); SET_PROGRESS_TEXT("Alle files completed successfully."); m_systemTray->showMessage("LameXP - Done", "All files completed successfully.", QSystemTrayIcon::Information); + m_systemTray->setIcon(QIcon(":/icons/cd_add.png")); QApplication::processEvents(); if(m_settings->soundsEnabled()) PlaySound(MAKEINTRESOURCE(IDR_WAVE_SUCCESS), GetModuleHandle(NULL), SND_RESOURCE | SND_SYNC); } diff --git a/src/Registry_Decoder.cpp b/src/Registry_Decoder.cpp index f58395ca..c815cbda 100644 --- a/src/Registry_Decoder.cpp +++ b/src/Registry_Decoder.cpp @@ -24,16 +24,18 @@ #include "Decoder_AAC.h" #include "Decoder_MP3.h" #include "Decoder_Vorbis.h" +#include "Decoder_WMA.h" #include -#define PROBE_DECODER(DEC) if(DEC::isFormatSupported(containerType, containerProfile, formatType, formatProfile, formatVersion)) { return new DEC(); } +#define PROBE_DECODER(DEC) if(DEC::isDecoderAvailable() && DEC::isFormatSupported(containerType, containerProfile, formatType, formatProfile, formatVersion)) { return new DEC(); } AbstractDecoder *DecoderRegistry::lookup(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion) { PROBE_DECODER(MP3Decoder); PROBE_DECODER(VorbisDecoder); PROBE_DECODER(AACDecoder); + PROBE_DECODER(WMADecoder); return NULL; }