diff --git a/res/Icons.qrc b/res/Icons.qrc
index 55439acf..01ca2f92 100644
--- a/res/Icons.qrc
+++ b/res/Icons.qrc
@@ -4,6 +4,7 @@
MainIcon.ico
MainIcon.png
icons/add.png
+ icons/accept.png
icons/application_view_list.png
icons/arrow_down.png
icons/arrow_up.png
@@ -39,6 +40,7 @@
icons/page_white_add.png
icons/page_white_cd.png
icons/play.png
+ icons/script_edit.png
icons/sound.png
icons/star.png
icons/table_edit.png
diff --git a/src/Config.h b/src/Config.h
index 1b2be3ea..f91ba959 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -28,6 +28,11 @@
#define VER_LAMEXP_BUILD 11
#define VER_LAMEXP_SUFFIX TechPreview
+/*
+ * Tools versions
+ */
+#define VER_LAMEXP_TOOL_NEROAAC 1540
+
/*
* Helper macros (aka: having fun with the C pre-processor)
*/
diff --git a/src/Dialog_About.cpp b/src/Dialog_About.cpp
index e07788e4..6cecd53e 100644
--- a/src/Dialog_About.cpp
+++ b/src/Dialog_About.cpp
@@ -29,6 +29,8 @@
#include
#include
#include
+#include
+#include
//Win32 includes
#include
@@ -43,7 +45,7 @@ const char *AboutDialog::neroAacUrl = "http://www.nero.com/eng/technologies-aac-
// Constructor
////////////////////////////////////////////////////////////
-AboutDialog::AboutDialog(QWidget *parent)
+AboutDialog::AboutDialog(QWidget *parent, bool firstStart)
: QMessageBox(parent)
{
QString aboutText;
@@ -73,17 +75,36 @@ AboutDialog::AboutDialog(QWidget *parent)
setIconPixmap(dynamic_cast(QApplication::instance())->windowIcon().pixmap(QSize(64,64)));
setWindowTitle("About LameXP");
- QPushButton *firstButton = addButton("More About...", QMessageBox::AcceptRole);
- firstButton->setIcon(QIcon(":/icons/information.png"));
- firstButton->setMinimumWidth(120);
+ if(firstStart)
+ {
+ QPushButton *firstButton = addButton("Show License Text", QMessageBox::AcceptRole);
+ firstButton->setIcon(QIcon(":/icons/script_edit.png"));
+ firstButton->setMinimumWidth(135);
- QPushButton *secondButton = addButton("About Qt...", QMessageBox::AcceptRole);
- secondButton->setIcon(QIcon(":/images/Qt.svg"));
- secondButton->setMinimumWidth(120);
+ QPushButton *secondButton = addButton("Accept License", QMessageBox::AcceptRole);
+ secondButton->setIcon(QIcon(":/icons/accept.png"));
+ secondButton->setMinimumWidth(120);
- QPushButton *thirdButton = addButton("Discard", QMessageBox::AcceptRole);
- thirdButton->setIcon(QIcon(":/icons/cross.png"));
- thirdButton->setMinimumWidth(90);
+ QPushButton *thirdButton = addButton("Decline License", QMessageBox::AcceptRole);
+ thirdButton->setIcon(QIcon(":/icons/delete.png"));
+ thirdButton->setMinimumWidth(120);
+ }
+ else
+ {
+ QPushButton *firstButton = addButton("More About...", QMessageBox::AcceptRole);
+ firstButton->setIcon(QIcon(":/icons/information.png"));
+ firstButton->setMinimumWidth(120);
+
+ QPushButton *secondButton = addButton("About Qt...", QMessageBox::AcceptRole);
+ secondButton->setIcon(QIcon(":/images/Qt.svg"));
+ secondButton->setMinimumWidth(120);
+
+ QPushButton *thirdButton = addButton("Discard", QMessageBox::AcceptRole);
+ thirdButton->setIcon(QIcon(":/icons/cross.png"));
+ thirdButton->setMinimumWidth(90);
+ }
+
+ m_firstShow = firstStart;
}
AboutDialog::~AboutDialog(void)
@@ -98,18 +119,38 @@ int AboutDialog::exec()
{
PlaySound(MAKEINTRESOURCE(IDR_WAVE_ABOUT), GetModuleHandle(NULL), SND_RESOURCE | SND_ASYNC);
- while(1)
+ if(m_firstShow)
{
- switch(QMessageBox::exec())
+ while(1)
{
- case 0:
- showMoreAbout();
- break;
- case 1:
- QMessageBox::aboutQt(dynamic_cast(this->parent()));
- break;
- default:
- return 0;
+ switch(QMessageBox::exec())
+ {
+ case 0:
+ QDesktopServices::openUrl(QUrl("http://www.gnu.org/licenses/gpl-2.0.txt"));
+ break;
+ case 1:
+ return 1;
+ break;
+ default:
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ while(1)
+ {
+ switch(QMessageBox::exec())
+ {
+ case 0:
+ showMoreAbout();
+ break;
+ case 1:
+ QMessageBox::aboutQt(dynamic_cast(this->parent()));
+ break;
+ default:
+ return 0;
+ }
}
}
diff --git a/src/Dialog_About.h b/src/Dialog_About.h
index f597d60f..976004d4 100644
--- a/src/Dialog_About.h
+++ b/src/Dialog_About.h
@@ -25,7 +25,7 @@
class AboutDialog : public QMessageBox
{
public:
- AboutDialog(QWidget *parent = 0);
+ AboutDialog(QWidget *parent = 0, bool firstStart = false);
~AboutDialog(void);
public slots:
@@ -34,4 +34,5 @@ public slots:
private:
void AboutDialog::showMoreAbout();
+ bool m_firstShow;
};
diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp
index 13ad56b5..327ea4e3 100644
--- a/src/Dialog_MainWindow.cpp
+++ b/src/Dialog_MainWindow.cpp
@@ -269,9 +269,28 @@ void MainWindow::windowShown(void)
{
QStringList arguments = QApplication::arguments();
+ AboutDialog *about = new AboutDialog(this, true);
+ int iAccepted = about->exec();
+ LAMEXP_DELETE(about);
+
+ if(iAccepted <= 0)
+ {
+ QApplication::quit();
+ return;
+ }
+
//Check for AAC support
if(lamexp_check_tool("neroAacEnc.exe") && lamexp_check_tool("neroAacDec.exe") && lamexp_check_tool("neroAacTag.exe"))
{
+ if(lamexp_tool_version("neroAacEnc.exe") < lamexp_toolver_neroaac())
+ {
+ QString messageText;
+ messageText += "LameXP detected that your version of the Nero AAC encoder is outdated!
";
+ messageText += "The current version available is " + lamexp_version2string("?.?.?.?", lamexp_toolver_neroaac()) + " (or later), but you still have version " + lamexp_version2string("?.?.?.?", lamexp_tool_version("neroAacEnc.exe")) + " installed.
";
+ messageText += "You can download the latest version of the Nero AAC encoder from the Nero website at:
";
+ messageText += "" + LINK(AboutDialog::neroAacUrl) + "
";
+ QMessageBox::information(this, "AAC Encoder Outdated", messageText);
+ }
radioButtonEncoderAAC->setEnabled(true);
}
else
@@ -279,7 +298,7 @@ void MainWindow::windowShown(void)
QString messageText;
messageText += "The Nero AAC encoder could not be found. AAC encoding support will be disabled.
";
messageText += "Please put 'neroAacEnc.exe', 'neroAacDec.exe' and 'neroAacTag.exe' into the LameXP directory!
";
- messageText += "You can download the Nero AAC encoder for free from the official Nero web-site at:
";
+ messageText += "You can download the Nero AAC encoder for free from the official Nero website at:
";
messageText += "" + LINK(AboutDialog::neroAacUrl) + "
";
QMessageBox::information(this, "AAC Support Disabled", messageText);
radioButtonEncoderAAC->setEnabled(false);
diff --git a/src/Global.cpp b/src/Global.cpp
index d9ea178d..24bded05 100644
--- a/src/Global.cpp
+++ b/src/Global.cpp
@@ -85,11 +85,15 @@ static QDate g_lamexp_version_date;
static const char *g_lamexp_months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
static const char *g_lamexp_version_raw_date = __DATE__;
+//Tool versions (expected)
+static const unsigned int g_lamexp_toolver_neroaac = VER_LAMEXP_TOOL_NEROAAC;
+
//Special folders
static QString g_lamexp_temp_folder;
//Tools
static QMap g_lamexp_tool_registry;
+static QMap g_lamexp_tool_versions;
//Shared memory
static const char *g_lamexp_sharedmem_uuid = "{21A68A42-6923-43bb-9CF6-64BF151942EE}";
@@ -113,6 +117,7 @@ unsigned int lamexp_version_major(void) { return g_lamexp_version_major; }
unsigned int lamexp_version_minor(void) { return g_lamexp_version_minor; }
unsigned int lamexp_version_build(void) { return g_lamexp_version_build; }
const char *lamexp_version_release(void) { return g_lamexp_version_release; }
+unsigned int lamexp_toolver_neroaac(void) { return g_lamexp_toolver_neroaac; }
bool lamexp_version_demo(void)
{
@@ -468,6 +473,7 @@ void lamexp_finalization(void)
LAMEXP_DELETE(g_lamexp_tool_registry[keys.at(i)]);
}
g_lamexp_tool_registry.clear();
+ g_lamexp_tool_versions.clear();
}
//Delete temporary files
@@ -495,7 +501,7 @@ void lamexp_finalization(void)
/*
* Register tool
*/
-void lamexp_register_tool(const QString &toolName, LockedFile *file)
+void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned int version)
{
if(g_lamexp_tool_registry.contains(toolName.toLower()))
{
@@ -503,6 +509,7 @@ void lamexp_register_tool(const QString &toolName, LockedFile *file)
}
g_lamexp_tool_registry.insert(toolName.toLower(), file);
+ g_lamexp_tool_versions.insert(toolName.toLower(), version);
}
/*
@@ -520,7 +527,7 @@ const QString lamexp_lookup_tool(const QString &toolName)
{
if(g_lamexp_tool_registry.contains(toolName.toLower()))
{
- return g_lamexp_tool_registry.value(toolName)->filePath();
+ return g_lamexp_tool_registry.value(toolName.toLower())->filePath();
}
else
{
@@ -528,6 +535,48 @@ const QString lamexp_lookup_tool(const QString &toolName)
}
}
+/*
+ * Lookup tool
+ */
+unsigned int lamexp_tool_version(const QString &toolName)
+{
+ if(g_lamexp_tool_versions.contains(toolName.toLower()))
+ {
+ return g_lamexp_tool_versions.value(toolName.toLower());
+ }
+ else
+ {
+ return UINT_MAX;
+ }
+}
+
+/*
+ * Version number to human-readable string
+ */
+const QString lamexp_version2string(const QString &pattern, unsigned int version)
+{
+ QString result = pattern;
+ int digits = result.count("?", Qt::CaseInsensitive);
+
+ if(digits < 1)
+ {
+ return result;
+ }
+
+ int pos = 0;
+ QString versionStr = QString().sprintf(QString().sprintf("%%0%du", digits).toLatin1().constData(), version);
+ int index = result.indexOf("?", Qt::CaseInsensitive);
+
+ while(index >= 0 && pos < versionStr.length())
+ {
+ result[index] = versionStr[pos++];
+ index = result.indexOf("?", Qt::CaseInsensitive);
+ }
+
+ return result;
+}
+
+
/*
* Get number private bytes [debug only]
*/
diff --git a/src/Global.h b/src/Global.h
index 0e03f37c..48265c5b 100644
--- a/src/Global.h
+++ b/src/Global.h
@@ -43,14 +43,16 @@ unsigned int lamexp_version_build(void);
const QDate &lamexp_version_date(void);
const char *lamexp_version_release(void);
bool lamexp_version_demo(void);
+unsigned int lamexp_toolver_neroaac(void);
//Public functions
void lamexp_init_console(int argc, char* argv[]);
bool lamexp_init_qt(int argc, char* argv[]);
int lamexp_init_ipc(void);
-void lamexp_register_tool(const QString &toolName, LockedFile *file);
+void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned int version = 0);
bool lamexp_check_tool(const QString &toolName);
const QString lamexp_lookup_tool(const QString &toolName);
+unsigned int lamexp_tool_version(const QString &toolName);
void lamexp_finalization(void);
const QString &lamexp_temp_folder(void);
void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize);
@@ -58,6 +60,7 @@ void lamexp_ipc_send(unsigned int command, const char* message);
//Auxiliary functions
bool lamexp_clean_folder(const QString folderPath);
+const QString lamexp_version2string(const QString &pattern, unsigned int version);
//Debug-only functions
SIZE_T lamexp_dbg_private_bytes(void);
diff --git a/src/Thread_FileAnalyzer.cpp b/src/Thread_FileAnalyzer.cpp
index e708dc12..dc19271e 100644
--- a/src/Thread_FileAnalyzer.cpp
+++ b/src/Thread_FileAnalyzer.cpp
@@ -112,7 +112,14 @@ const AudioFileModel FileAnalyzer::analyzeFile(const QString &filePath)
process.setProcessChannelMode(QProcess::MergedChannels);
process.setReadChannel(QProcess::StandardOutput);
process.start(m_mediaInfoBin, QStringList() << QDir::toNativeSeparators(filePath));
- process.waitForStarted();
+
+ if(!process.waitForStarted())
+ {
+ qWarning("MediaInfo process failed to create!");
+ process.kill();
+ process.waitForFinished(-1);
+ return audioFile;
+ }
while(process.state() != QProcess::NotRunning)
{
diff --git a/src/Thread_Initialization.cpp b/src/Thread_Initialization.cpp
index 57911550..277a7bc1 100644
--- a/src/Thread_Initialization.cpp
+++ b/src/Thread_Initialization.cpp
@@ -26,6 +26,7 @@
#include
#include
+#include
////////////////////////////////////////////////////////////
// TOOLS
@@ -73,19 +74,9 @@ InitializationThread::InitializationThread(void)
m_bSuccess = false;
}
-void InitializationThread::delay(void)
-{
- const char *temp = "|/-\\";
- printf("Thread is doing something important... ?\b", temp[4]);
-
- for(int i = 0; i < 20; i++)
- {
- printf("%c\b", temp[i%4]);
- msleep(100);
- }
-
- printf("Done\n\n");
-}
+////////////////////////////////////////////////////////////
+// Thread Main
+////////////////////////////////////////////////////////////
void InitializationThread::run()
{
@@ -118,6 +109,32 @@ void InitializationThread::run()
qDebug("All extracted.\n");
//Look for Nero encoder
+ initNeroAac();
+
+ delay();
+ m_bSuccess = true;
+}
+
+////////////////////////////////////////////////////////////
+// PUBLIC FUNCTIONS
+////////////////////////////////////////////////////////////
+
+void InitializationThread::delay(void)
+{
+ const char *temp = "|/-\\";
+ printf("Thread is doing something important... ?\b", temp[4]);
+
+ for(int i = 0; i < 20; i++)
+ {
+ printf("%c\b", temp[i%4]);
+ msleep(100);
+ }
+
+ printf("Done\n\n");
+}
+
+void InitializationThread::initNeroAac(void)
+{
QFileInfo neroFileInfo[3];
neroFileInfo[0] = QFileInfo(QString("%1/neroAacEnc.exe").arg(QCoreApplication::applicationDirPath()));
neroFileInfo[1] = QFileInfo(QString("%1/neroAacDec.exe").arg(QCoreApplication::applicationDirPath()));
@@ -127,29 +144,95 @@ void InitializationThread::run()
for(int i = 0; i < 3; i++) { if(!neroFileInfo[i].exists()) neroFilesFound = false; }
//Lock the Nero binaries
- if(neroFilesFound)
- {
- qDebug("Found Nero AAC encoder binary:\n%s\n", neroFileInfo[0].absoluteFilePath().toUtf8().constData());
- LockedFile *neroBin[3];
- for(int i = 0; i < 3; i++) neroBin[i] = NULL;
- try
- {
- for(int i = 0; i < 3; i++) { neroBin[i] = new LockedFile(neroFileInfo[i].absoluteFilePath()); }
- for(int i = 0; i < 3; i++) { lamexp_register_tool(neroFileInfo[i].fileName(), neroBin[i]); }
- }
- catch(...)
- {
- for(int i = 0; i < 3; i++) LAMEXP_DELETE(neroBin[i]);
- qWarning("Failed to lock Nero encoder binary -> AAC encoding support will be disabled!");
- }
- }
- else
+ if(!neroFilesFound)
{
qDebug("Nero encoder binaries not found -> AAC encoding support will be disabled!\n");
+ return;
+ }
+
+ qDebug("Found Nero AAC encoder binary:\n%s\n", neroFileInfo[0].absoluteFilePath().toUtf8().constData());
+
+ LockedFile *neroBin[3];
+ for(int i = 0; i < 3; i++) neroBin[i] = NULL;
+
+ try
+ {
+ for(int i = 0; i < 3; i++)
+ {
+ neroBin[i] = new LockedFile(neroFileInfo[i].absoluteFilePath());
+ }
+ }
+ catch(...)
+ {
+ for(int i = 0; i < 3; i++) LAMEXP_DELETE(neroBin[i]);
+ qWarning("Failed to lock Nero encoder binary -> AAC encoding support will be disabled!");
+ return;
+ }
+
+ QProcess process;
+ process.setProcessChannelMode(QProcess::MergedChannels);
+ process.setReadChannel(QProcess::StandardOutput);
+ process.start(neroFileInfo[0].absoluteFilePath());
+
+ if(!process.waitForStarted())
+ {
+ qWarning("Nero process failed to create!");
+ process.kill();
+ process.waitForFinished(-1);
+ for(int i = 0; i < 3; i++) LAMEXP_DELETE(neroBin[i]);
+ return;
+ }
+
+ unsigned int neroVersion = 0;
+
+ while(process.state() != QProcess::NotRunning)
+ {
+ if(!process.waitForReadyRead())
+ {
+ if(process.state() == QProcess::Running)
+ {
+ qWarning("Nero process time out -> killing!");
+ process.kill();
+ process.waitForFinished(-1);
+ for(int i = 0; i < 3; i++) LAMEXP_DELETE(neroBin[i]);
+ return;
+ }
+ }
+
+ QByteArray data = process.readLine();
+ while(!data.isEmpty())
+ {
+ QString line = QString::fromUtf8(data.constData()).simplified();
+ QStringList tokens = line.split(" ", QString::SkipEmptyParts, Qt::CaseInsensitive);
+ int index1 = tokens.indexOf("Package");
+ int index2 = tokens.indexOf("version:");
+ if(index1 >= 0 && index2 >= 0 && index1 + 1 == index2 && index2 < tokens.count() - 1)
+ {
+ QStringList versionTokens = tokens.at(index2 + 1).split(".", QString::SkipEmptyParts, Qt::CaseInsensitive);
+ if(versionTokens.count() == 4)
+ {
+ neroVersion = 0;
+ neroVersion += versionTokens.at(3).toInt();
+ neroVersion += versionTokens.at(2).toInt() * 10;
+ neroVersion += versionTokens.at(1).toInt() * 100;
+ neroVersion += versionTokens.at(0).toInt() * 1000;
+ }
+ }
+ data = process.readLine();
+ }
+ }
+
+ if(!(neroVersion > 0))
+ {
+ qWarning("Nero AAC version could not be determined!", neroVersion);
+ for(int i = 0; i < 3; i++) LAMEXP_DELETE(neroBin[i]);
+ return;
}
- delay();
- m_bSuccess = true;
+ for(int i = 0; i < 3; i++)
+ {
+ lamexp_register_tool(neroFileInfo[i].fileName(), neroBin[i], neroVersion);
+ }
}
////////////////////////////////////////////////////////////
diff --git a/src/Thread_Initialization.h b/src/Thread_Initialization.h
index 3962cf69..ea3a083c 100644
--- a/src/Thread_Initialization.h
+++ b/src/Thread_Initialization.h
@@ -38,5 +38,7 @@ public:
private:
void delay(void);
+ void initNeroAac(void);
+
bool m_bSuccess;
};