diff --git a/gui/MainWindow.ui b/gui/MainWindow.ui
index 33c9e5cd..112f830e 100644
--- a/gui/MainWindow.ui
+++ b/gui/MainWindow.ui
@@ -1346,6 +1346,8 @@
+
+
@@ -1620,5 +1622,21 @@
+
+ saveToSourceFolderCheckBox
+ toggled(bool)
+ generatePlaylistCheckBox
+ setDisabled(bool)
+
+
+ 70
+ 79
+
+
+ 70
+ 79
+
+
+
diff --git a/src/Config.h b/src/Config.h
index 86ffafc3..b214dbb3 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 57
+#define VER_LAMEXP_BUILD 60
#define VER_LAMEXP_SUFFIX TechPreview
/*
diff --git a/src/Dialog_Processing.cpp b/src/Dialog_Processing.cpp
index 6476cb0e..35571a07 100644
--- a/src/Dialog_Processing.cpp
+++ b/src/Dialog_Processing.cpp
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
@@ -84,6 +85,8 @@ ProcessingDialog::ProcessingDialog(FileListModel *fileListModel, AudioFileModel
view_log->verticalHeader()->hide();
view_log->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
view_log->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
+ connect(m_progressModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(progressModelChanged()));
+ connect(m_progressModel, SIGNAL(modelReset()), this, SLOT(progressModelChanged()));
//Enque jobs
if(fileListModel)
@@ -97,6 +100,8 @@ ProcessingDialog::ProcessingDialog(FileListModel *fileListModel, AudioFileModel
//Init other vars
m_runningThreads = 0;
m_currentFile = 0;
+ m_succeededFiles = 0;
+ m_failedFiles = 0;
m_userAborted = false;
}
@@ -175,6 +180,8 @@ void ProcessingDialog::initEncoding(void)
{
m_runningThreads = 0;
m_currentFile = 0;
+ m_succeededFiles = 0;
+ m_failedFiles = 0;
m_userAborted = false;
m_playList.clear();
@@ -228,20 +235,34 @@ void ProcessingDialog::doneEncoding(void)
qDebug("Running jobs: %u", m_runningThreads);
- if(!m_userAborted && m_settings->createPlaylist() && !m_settings->outputDir().isEmpty())
+ if(!m_userAborted && m_settings->createPlaylist() && !m_settings->outputToSourceDir())
{
- label_progress->setText("Creatig the play list, please wait...");
+ label_progress->setText("Creatig the playlist file, please wait...");
QApplication::processEvents();
writePlayList();
}
- label_progress->setText(m_userAborted ? "Process was aborted by the user!" : "Alle files completed successfully.");
- m_progressIndicator->stop();
-
+ if(m_userAborted)
+ {
+ label_progress->setText("Process was aborted by the user!");
+ }
+ else
+ {
+ if(m_failedFiles)
+ {
+ label_progress->setText(QString("Error: %1 of %2 files failed. See the log for details!").arg(QString::number(m_failedFiles), QString::number(m_failedFiles + m_succeededFiles)));
+ }
+ else
+ {
+ label_progress->setText("Alle files completed successfully.");
+ }
+ }
+
setCloseButtonEnabled(true);
button_closeDialog->setEnabled(true);
button_AbortProcess->setEnabled(false);
+ m_progressIndicator->stop();
progressBar->setValue(100);
}
@@ -249,8 +270,18 @@ void ProcessingDialog::processFinished(const QUuid &jobId, const QString &outFil
{
if(success)
{
+ m_succeededFiles++;
m_playList.append(outFileName);
}
+ else
+ {
+ m_failedFiles++;
+ }
+}
+
+void ProcessingDialog::progressModelChanged(void)
+{
+ view_log->scrollToBottom();
}
////////////////////////////////////////////////////////////
@@ -281,8 +312,8 @@ void ProcessingDialog::startNextJob(void)
default:
throw "Unsupported encoder!";
}
-
- ProcessThread *thread = new ProcessThread(currentFile, m_settings->outputDir(), encoder);
+
+ ProcessThread *thread = new ProcessThread(currentFile, (m_settings->outputToSourceDir() ? QFileInfo(currentFile.filePath()).absolutePath(): m_settings->outputDir()), encoder);
m_threadList.append(thread);
connect(thread, SIGNAL(finished()), this, SLOT(doneEncoding()), Qt::QueuedConnection);
connect(thread, SIGNAL(processStateInitialized(QUuid,QString,QString,int)), m_progressModel, SLOT(addJob(QUuid,QString,QString,int)), Qt::QueuedConnection);
@@ -322,6 +353,10 @@ void ProcessingDialog::writePlayList(void)
}
playList.close();
}
+ else
+ {
+ QMessageBox::warning(this, "Playlist creation failed", QString("The playlist file could not be created:
%1").arg(playListFile));
+ }
}
AudioFileModel ProcessingDialog::updateMetaInfo(const AudioFileModel &audioFile)
diff --git a/src/Dialog_Processing.h b/src/Dialog_Processing.h
index fb352320..97aa9ab5 100644
--- a/src/Dialog_Processing.h
+++ b/src/Dialog_Processing.h
@@ -45,6 +45,7 @@ private slots:
void doneEncoding(void);
void abortEncoding(void);
void processFinished(const QUuid &jobId, const QString &outFileName, bool success);
+ void progressModelChanged(void);
protected:
void showEvent(QShowEvent *event);
@@ -66,5 +67,7 @@ private:
QStringList m_playList;
unsigned int m_runningThreads;
unsigned int m_currentFile;
+ unsigned int m_succeededFiles;
+ unsigned int m_failedFiles;
bool m_userAborted;
};
diff --git a/src/Global.cpp b/src/Global.cpp
index 992c7855..c9e8849e 100644
--- a/src/Global.cpp
+++ b/src/Global.cpp
@@ -208,6 +208,7 @@ void lamexp_message_handler(QtMsgType type, const char *msg)
CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
GetConsoleScreenBufferInfo(hConsole, &bufferInfo);
+ SetConsoleOutputCP(CP_UTF8);
switch(type)
{
@@ -216,17 +217,18 @@ void lamexp_message_handler(QtMsgType type, const char *msg)
fflush(stdout);
fflush(stderr);
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- fprintf(stderr, "\nCRITICAL ERROR !!!\n%s\n\n", msg);
+ fwprintf(stderr, L"\nCRITICAL ERROR !!!\n%S\n\n", msg);
MessageBoxW(NULL, (wchar_t*) QString::fromUtf8(msg).utf16(), L"LameXP - CRITICAL ERROR", MB_ICONERROR | MB_TOPMOST | MB_TASKMODAL);
break;
case QtWarningMsg:
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
- fprintf(stderr, "%s\n", msg);
+ fwprintf(stderr, L"%S\n", msg);
fflush(stderr);
+ //MessageBoxW(NULL, (wchar_t*) QString::fromUtf8(msg).utf16(), NULL, MB_TOPMOST | MB_ICONWARNING);
break;
default:
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
- fprintf(stderr, "%s\n", msg);
+ fwprintf(stderr, L"%S\n", msg);
fflush(stderr);
break;
}
diff --git a/src/Main.cpp b/src/Main.cpp
index 30c3c8f7..062fa9e0 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
///////////////////////////////////////////////////////////////////////////////
// Main function
@@ -72,7 +73,7 @@ int lamexp_main(int argc, char* argv[])
//Initialize Qt
lamexp_init_qt(argc, argv);
-
+
//Check for expiration
if(lamexp_version_demo())
{
diff --git a/src/Model_Progress.cpp b/src/Model_Progress.cpp
index 2b6dddc5..cc04b849 100644
--- a/src/Model_Progress.cpp
+++ b/src/Model_Progress.cpp
@@ -136,13 +136,14 @@ void ProgressModel::addJob(const QUuid &jobId, const QString &jobName, const QSt
void ProgressModel::updateJob(const QUuid &jobId, const QString &newStatus, int newState)
{
- if(!m_jobList.contains(jobId))
+ int row = m_jobList.indexOf(jobId);
+
+ if(row < 0)
{
return;
}
- beginResetModel();
if(!newStatus.isEmpty()) m_jobStatus.insert(jobId, newStatus);
if(newState >= 0) m_jobState.insert(jobId, newState);
- endResetModel();
+ emit dataChanged(index(row, 0), index(row, 1));
}
diff --git a/src/Model_Settings.cpp b/src/Model_Settings.cpp
index 4b272ae0..489717ba 100644
--- a/src/Model_Settings.cpp
+++ b/src/Model_Settings.cpp
@@ -29,23 +29,32 @@
#include
#include
+//Constants
static const char *g_settingsId_versionNumber = "VersionNumber";
static const char *g_settingsId_licenseAccepted = "LicenseAccepted";
static const char *g_settingsId_interfaceStyle = "InterfaceStyle";
static const char *g_settingsId_compressionEncoder = "Compression/Encoder";
static const char *g_settingsId_compressionRCMode = "Compression/RCMode";
static const char *g_settingsId_compressionBitrate = "Compression/Bitrate";
-static const char *g_settingsId_outputDir = "OutputDirectory";
+static const char *g_settingsId_outputDir = "OutputDirectory/SelectedPath";
+static const char *g_settingsId_outputToSourceDir = "OutputDirectory/OutputToSourceFolder";
static const char *g_settingsId_writeMetaTags = "WriteMetaTags";
static const char *g_settingsId_createPlaylist = "AutoCreatePlaylist";
-#define MAKE_GETTER1(OPT,DEF) int SettingsModel::OPT(void) { return m_settings->value(g_settingsId_##OPT, DEF).toInt(); }
-#define MAKE_SETTER1(OPT) void SettingsModel::OPT(int value) { m_settings->setValue(g_settingsId_##OPT, value); }
-#define MAKE_GETTER2(OPT,DEF) QString SettingsModel::OPT(void) { return m_settings->value(g_settingsId_##OPT, DEF).toString().trimmed(); }
-#define MAKE_SETTER2(OPT) void SettingsModel::OPT(const QString &value) { m_settings->setValue(g_settingsId_##OPT, value); }
-#define MAKE_GETTER3(OPT,DEF) bool SettingsModel::OPT(void) { return m_settings->value(g_settingsId_##OPT, DEF).toBool(); }
-#define MAKE_SETTER3(OPT) void SettingsModel::OPT(bool value) { m_settings->setValue(g_settingsId_##OPT, value); }
+//Macros
+#define MAKE_OPTION1(OPT,DEF) \
+int SettingsModel::OPT(void) { return m_settings->value(g_settingsId_##OPT, DEF).toInt(); } \
+void SettingsModel::OPT(int value) { m_settings->setValue(g_settingsId_##OPT, value); }
+#define MAKE_OPTION2(OPT,DEF) \
+QString SettingsModel::OPT(void) { return m_settings->value(g_settingsId_##OPT, DEF).toString().trimmed(); } \
+void SettingsModel::OPT(const QString &value) { m_settings->setValue(g_settingsId_##OPT, value); }
+
+#define MAKE_OPTION3(OPT,DEF) \
+bool SettingsModel::OPT(void) { return m_settings->value(g_settingsId_##OPT, DEF).toBool(); } \
+void SettingsModel::OPT(bool value) { m_settings->setValue(g_settingsId_##OPT, value); }
+
+//LUT
const int SettingsModel::mp3Bitrates[15] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1};
////////////////////////////////////////////////////////////
@@ -98,26 +107,12 @@ void SettingsModel::validate(void)
// Getter and Setter
////////////////////////////////////////////////////////////
-MAKE_GETTER1(licenseAccepted, 0)
-MAKE_SETTER1(licenseAccepted)
-
-MAKE_GETTER1(interfaceStyle, 0)
-MAKE_SETTER1(interfaceStyle)
-
-MAKE_GETTER1(compressionEncoder, 0)
-MAKE_SETTER1(compressionEncoder)
-
-MAKE_GETTER1(compressionRCMode, 0)
-MAKE_SETTER1(compressionRCMode)
-
-MAKE_GETTER1(compressionBitrate, 7)
-MAKE_SETTER1(compressionBitrate)
-
-MAKE_GETTER2(outputDir, QString())
-MAKE_SETTER2(outputDir)
-
-MAKE_GETTER3(writeMetaTags, true)
-MAKE_SETTER3(writeMetaTags)
-
-MAKE_GETTER3(createPlaylist, true)
-MAKE_SETTER3(createPlaylist)
+MAKE_OPTION1(licenseAccepted, 0)
+MAKE_OPTION1(interfaceStyle, 0)
+MAKE_OPTION1(compressionEncoder, 0)
+MAKE_OPTION1(compressionRCMode, 0)
+MAKE_OPTION1(compressionBitrate, 7)
+MAKE_OPTION2(outputDir, QString())
+MAKE_OPTION3(outputToSourceDir, false)
+MAKE_OPTION3(writeMetaTags, true)
+MAKE_OPTION3(createPlaylist, true)
diff --git a/src/Model_Settings.h b/src/Model_Settings.h
index c5ed184c..89fadf83 100644
--- a/src/Model_Settings.h
+++ b/src/Model_Settings.h
@@ -24,12 +24,17 @@
class QSettings;
class QString;
-#define MAKE_GETTER_DEC1(OPT) int OPT(void)
-#define MAKE_SETTER_DEC1(OPT) void OPT(int value)
-#define MAKE_GETTER_DEC2(OPT) QString OPT(void)
-#define MAKE_SETTER_DEC2(OPT) void OPT(const QString &value)
-#define MAKE_GETTER_DEC3(OPT) bool OPT(void)
-#define MAKE_SETTER_DEC3(OPT) void OPT(bool value)
+#define MAKE_OPTION_DEC1(OPT) \
+int OPT(void); \
+void OPT(int value);
+
+#define MAKE_OPTION_DEC2(OPT) \
+QString OPT(void); \
+void OPT(const QString &value);
+
+#define MAKE_OPTION_DEC3(OPT) \
+bool OPT(void); \
+void OPT(bool value);
class SettingsModel
{
@@ -56,35 +61,24 @@ public:
//Consts
static const int mp3Bitrates[15];
- //Getters
- MAKE_GETTER_DEC1(licenseAccepted);
- MAKE_GETTER_DEC1(interfaceStyle);
- MAKE_GETTER_DEC1(compressionEncoder);
- MAKE_GETTER_DEC1(compressionRCMode);
- MAKE_GETTER_DEC1(compressionBitrate);
- MAKE_GETTER_DEC2(outputDir);
- MAKE_GETTER_DEC3(writeMetaTags);
- MAKE_GETTER_DEC3(createPlaylist);
-
- //Setters
- MAKE_SETTER_DEC1(licenseAccepted);
- MAKE_SETTER_DEC1(interfaceStyle);
- MAKE_SETTER_DEC1(compressionBitrate);
- MAKE_SETTER_DEC1(compressionRCMode);
- MAKE_SETTER_DEC1(compressionEncoder);
- MAKE_SETTER_DEC2(outputDir);
- MAKE_SETTER_DEC3(writeMetaTags);
- MAKE_SETTER_DEC3(createPlaylist);
+ //Getters & setters
+ MAKE_OPTION_DEC1(licenseAccepted);
+ MAKE_OPTION_DEC1(interfaceStyle);
+ MAKE_OPTION_DEC1(compressionEncoder);
+ MAKE_OPTION_DEC1(compressionRCMode);
+ MAKE_OPTION_DEC1(compressionBitrate);
+ MAKE_OPTION_DEC2(outputDir);
+ MAKE_OPTION_DEC3(outputToSourceDir);
+ MAKE_OPTION_DEC3(writeMetaTags);
+ MAKE_OPTION_DEC3(createPlaylist);
+ //Misc
void validate(void);
private:
QSettings *m_settings;
};
-#undef MAKE_GETTER_DEC1
-#undef MAKE_SETTER_DEC1
-#undef MAKE_GETTER_DEC2
-#undef MAKE_SETTER_DEC2
-#undef MAKE_GETTER_DEC3
-#undef MAKE_SETTER_DEC3
+#undef MAKE_OPTION_DEC1
+#undef MAKE_OPTION_DEC2
+#undef MAKE_OPTION_DEC3
diff --git a/src/Thread_Process.cpp b/src/Thread_Process.cpp
index 38101aa9..59d57c7c 100644
--- a/src/Thread_Process.cpp
+++ b/src/Thread_Process.cpp
@@ -71,13 +71,13 @@ void ProcessThread::run()
qDebug("Process thread %s has started.", m_jobId.toString().toLatin1().constData());
emit processStateInitialized(m_jobId, QFileInfo(m_audioFile.filePath()).fileName(), "Starting...", ProgressModel::JobRunning);
- if(!QFileInfo(m_audioFile.filePath()).isFile())
+ QString outFileName = generateOutFileName();
+ if(outFileName.isEmpty())
{
emit processStateChanged(m_jobId, "Not found!", ProgressModel::JobFailed);
return;
}
- QString outFileName = generateOutFileName();
bool bSuccess = m_encoder->encode(m_audioFile, outFileName, &m_aborted);
if(bSuccess)
@@ -111,14 +111,28 @@ QString ProcessThread::generateOutFileName(void)
int n = 1;
- QString baseName = QFileInfo(m_audioFile.filePath()).completeBaseName();
- QString targetDir = m_outputDirectory.isEmpty() ? QFileInfo(m_audioFile.filePath()).canonicalPath() : m_outputDirectory;
- QDir(targetDir).mkpath(".");
- QString outFileName = QString("%1/%2.%3").arg(targetDir, baseName, "mp3");
+ QFileInfo sourceFile(m_audioFile.filePath());
+ if(!sourceFile.exists() || !sourceFile.isFile())
+ {
+ return QString();
+ }
+ QString baseName = sourceFile.completeBaseName();
+ QDir targetDir(m_outputDirectory.isEmpty() ? sourceFile.canonicalPath() : m_outputDirectory);
+
+ if(!targetDir.exists())
+ {
+ targetDir.mkpath(".");
+ if(!targetDir.exists())
+ {
+ return QString();
+ }
+ }
+
+ QString outFileName = QString("%1/%2.%3").arg(targetDir.canonicalPath(), baseName, "mp3");
while(QFileInfo(outFileName).exists())
{
- outFileName = QString("%1/%2 (%3).%4").arg(targetDir, baseName, QString::number(++n), m_encoder->extension());
+ outFileName = QString("%1/%2 (%3).%4").arg(targetDir.canonicalPath(), baseName, QString::number(++n), m_encoder->extension());
}
QFile placeholder(outFileName);