From 1633489aaf467be74f7689c62f714f67fa10505e Mon Sep 17 00:00:00 2001 From: lordmulder Date: Sat, 20 Nov 2010 02:14:22 +0100 Subject: [PATCH] Actually use selected encoder in progress dialog + forward output dir. --- LameXP.vcproj | 34 +++++++++++++++++ src/Config.h | 2 +- src/Dialog_MainWindow.cpp | 78 +++++++++++++++++++++------------------ src/Dialog_MainWindow.h | 5 +++ src/Dialog_Processing.cpp | 39 +++++++++++++++++--- src/Dialog_Processing.h | 4 +- src/Encoder_Abstract.h | 9 +++-- src/Encoder_MP3.cpp | 43 ++++++++++++++++----- src/Encoder_MP3.h | 7 ++-- src/Main.cpp | 4 +- src/Model_FileList.cpp | 4 +- src/Model_Progress.cpp | 4 ++ src/Model_Settings.cpp | 13 +++++++ src/Model_Settings.h | 7 ++++ src/Thread_Process.cpp | 66 +++++++++++++++++++++++++-------- src/Thread_Process.h | 10 ++++- 16 files changed, 252 insertions(+), 77 deletions(-) diff --git a/LameXP.vcproj b/LameXP.vcproj index 7643831f..54117fe3 100644 --- a/LameXP.vcproj +++ b/LameXP.vcproj @@ -595,6 +595,36 @@ + + + + + + + + + + + diff --git a/src/Config.h b/src/Config.h index 314962cf..79305c6a 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 44 +#define VER_LAMEXP_BUILD 49 #define VER_LAMEXP_SUFFIX TechPreview /* diff --git a/src/Dialog_MainWindow.cpp b/src/Dialog_MainWindow.cpp index a036f10f..b5021d0a 100644 --- a/src/Dialog_MainWindow.cpp +++ b/src/Dialog_MainWindow.cpp @@ -114,12 +114,18 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S sourceFileView->setModel(m_fileListModel); sourceFileView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); sourceFileView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); + m_dropNoteLabel = new QLabel(sourceFileView); + m_dropNoteLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + m_dropNoteLabel->setText("» You can drop in audio files here! «"); connect(buttonAddFiles, SIGNAL(clicked()), this, SLOT(addFilesButtonClicked())); connect(buttonRemoveFile, SIGNAL(clicked()), this, SLOT(removeFileButtonClicked())); connect(buttonClearFiles, SIGNAL(clicked()), this, SLOT(clearFilesButtonClicked())); connect(buttonFileUp, SIGNAL(clicked()), this, SLOT(fileUpButtonClicked())); connect(buttonFileDown, SIGNAL(clicked()), this, SLOT(fileDownButtonClicked())); connect(buttonShowDetails, SIGNAL(clicked()), this, SLOT(showDetailsButtonClicked())); + connect(m_fileListModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsChanged(QModelIndex,int,int))); + connect(m_fileListModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(rowsChanged(QModelIndex,int,int))); + connect(m_fileListModel, SIGNAL(modelReset()), this, SLOT(modelReset())); //Setup "Output" tab m_fileSystemModel = new QFileSystemModel(); @@ -133,7 +139,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S outputFolderView->setHeaderHidden(true); outputFolderView->setAnimated(true); connect(outputFolderView, SIGNAL(clicked(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); - outputFolderView->setCurrentIndex(m_fileSystemModel->index(QDesktopServices::storageLocation(QDesktopServices::MusicLocation))); + outputFolderView->setCurrentIndex(m_fileSystemModel->index(m_settings->outputDir())); outputFolderViewClicked(outputFolderView->currentIndex()); connect(buttonMakeFolder, SIGNAL(clicked()), this, SLOT(makeFolderButtonClicked())); connect(buttonGotoHome, SIGNAL(clicked()), SLOT(gotoHomeFolderButtonClicked())); @@ -269,6 +275,7 @@ MainWindow::~MainWindow(void) LAMEXP_DELETE(m_delayedFileTimer); LAMEXP_DELETE(m_metaInfoModel); LAMEXP_DELETE(m_encoderButtonGroup); + LAMEXP_DELETE(m_encoderButtonGroup); } //////////////////////////////////////////////////////////// @@ -310,8 +317,10 @@ void MainWindow::addFiles(const QStringList &files) void MainWindow::showEvent(QShowEvent *event) { - QTimer::singleShot(0, this, SLOT(windowShown())); m_accepted = false; + m_dropNoteLabel->setGeometry(0, 0, sourceFileView->width(), sourceFileView->height()); + modelReset(); + QTimer::singleShot(0, this, SLOT(windowShown())); } void MainWindow::dragEnterEvent(QDragEnterEvent *event) @@ -365,6 +374,12 @@ void MainWindow::closeEvent(QCloseEvent *event) } } +void MainWindow::resizeEvent(QResizeEvent *event) +{ + QMainWindow::resizeEvent(event); + m_dropNoteLabel->setGeometry(0, 0, sourceFileView->width(), sourceFileView->height()); +} + //////////////////////////////////////////////////////////// // Slots //////////////////////////////////////////////////////////// @@ -450,8 +465,6 @@ void MainWindow::aboutButtonClicked(void) LAMEXP_DELETE(aboutBox); } -#define IF_UNICODE(STR) if(_stricmp(STR.toUtf8().constData(),QString::fromLocal8Bit(STR.toLocal8Bit()).toUtf8().constData())) - /* * Encode button */ @@ -459,46 +472,22 @@ void MainWindow::encodeButtonClicked(void) { ABORT_IF_BUSY; + if(m_fileListModel->rowCount() < 1) + { + QMessageBox::warning(this, "LameXP", "You must add at least one file to the list before proceeding!"); + tabWidget->setCurrentIndex(0); + return; + } + if(m_settings->compressionEncoder() != SettingsModel::MP3Encoder) { - QMessageBox::warning(this, "LameXP", "Sorry, only Lame MP3 is supported at the moment!"); + QMessageBox::warning(this, "LameXP", "Sorry, only Lame MP3 encoding is supported at the moment!"); tabWidget->setCurrentIndex(3); return; } m_accepted = true; close(); - - //m_banner->show("Encoding files, please wait..."); - //QApplication::processEvents(); - - //MP3Encoder *mp3Encoder = new MP3Encoder(); - //connect(mp3Encoder, SIGNAL(statusUpdated(QString)), m_banner, SLOT(setText(QString))); - - //for(int i = 0; i < m_fileListModel->rowCount(); i++) - //{ - // AudioFileModel file = m_fileListModel->getFile(m_fileListModel->index(i,0)); - // QString outFolder = m_fileSystemModel->filePath(this->outputFolderView->currentIndex()); - // - // QString baseName = QFileInfo(file.filePath()).fileName(); - // int pos = baseName.lastIndexOf("."); - // if(pos >= 1) baseName = baseName.left(pos); - - // int n = 1; - // QString outFileName = QString(outFolder).append("/").append(baseName).append(".mp3"); - // - // while(QFileInfo(outFileName).exists()) - // { - // outFileName = QString(outFolder).append("/").append(baseName).append(" (").append(QString::number(++n)).append(").mp3"); - // } - // - // mp3Encoder->encode(file, outFileName); - //} - - //LAMEXP_DELETE(mp3Encoder); - //m_banner->close(); - // - //QMessageBox::information(this, "Done", "Encoding process completed."); } /* @@ -693,6 +682,7 @@ void MainWindow::outputFolderViewClicked(const QModelIndex &index) QString selectedDir = m_fileSystemModel->filePath(index); if(selectedDir.length() < 3) selectedDir.append(QDir::separator()); outputFolderLabel->setText(selectedDir); + m_settings->outputDir(selectedDir); } /* @@ -1060,3 +1050,19 @@ void MainWindow::updateBitrate(int value) break; } } + +/* + * Rows changed + */ +void MainWindow::rowsChanged(const QModelIndex &parent, int start, int end) +{ + m_dropNoteLabel->setVisible(m_fileListModel->rowCount() <= 0); +} + +/* + * Model reset + */ +void MainWindow::modelReset(void) +{ + m_dropNoteLabel->setVisible(m_fileListModel->rowCount() <= 0); +} diff --git a/src/Dialog_MainWindow.h b/src/Dialog_MainWindow.h index 8037ecf0..99c28fdd 100644 --- a/src/Dialog_MainWindow.h +++ b/src/Dialog_MainWindow.h @@ -34,6 +34,7 @@ class MetaInfoModel; class SettingsModel; class QButtonGroup; class FileListModel; +class AbstractEncoder; class MainWindow: public QMainWindow, private Ui::MainWindow { @@ -75,12 +76,15 @@ private slots: void updateEncoder(int id); void updateRCMode(int id); void updateBitrate(int value); + void rowsChanged(const QModelIndex &parent, int start, int end); + void modelReset(void); protected: void showEvent(QShowEvent *event); void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); void closeEvent(QCloseEvent *event); + void resizeEvent(QResizeEvent *event); private: void addFiles(const QStringList &files); @@ -99,4 +103,5 @@ private: AudioFileModel *m_metaData; MetaInfoModel *m_metaInfoModel; SettingsModel *m_settings; + QLabel *m_dropNoteLabel; }; diff --git a/src/Dialog_Processing.cpp b/src/Dialog_Processing.cpp index 77257b30..54f1fc56 100644 --- a/src/Dialog_Processing.cpp +++ b/src/Dialog_Processing.cpp @@ -24,7 +24,9 @@ #include "Global.h" #include "Model_FileList.h" #include "Model_Progress.h" +#include "Model_Settings.h" #include "Thread_Process.h" +#include "Encoder_MP3.h" #include #include @@ -41,7 +43,9 @@ // Constructor //////////////////////////////////////////////////////////// -ProcessingDialog::ProcessingDialog(FileListModel *fileListModel) +ProcessingDialog::ProcessingDialog(FileListModel *fileListModel, SettingsModel *settings) +: + m_settings(settings) { //Init the dialog, from the .ui file setupUi(this); @@ -103,7 +107,10 @@ ProcessingDialog::~ProcessingDialog(void) while(!m_threadList.isEmpty()) { - delete m_threadList.takeFirst(); + ProcessThread *thread = m_threadList.takeFirst(); + thread->terminate(); + thread->wait(15000); + delete thread; } } @@ -190,8 +197,14 @@ void ProcessingDialog::doneEncoding(void) m_runningThreads--; progressBar->setValue(progressBar->value() + 1); - label_progress->setText(QString("%1 files out of %2 completed, please wait...").arg(QString::number(progressBar->value()), QString::number(progressBar->maximum()))); + label_progress->setText(QString("Encoding: %1 files of %2 completed so far, please wait...").arg(QString::number(progressBar->value()), QString::number(progressBar->maximum()))); + int index = m_threadList.indexOf(dynamic_cast(QWidget::sender())); + if(index >= 0) + { + m_threadList.takeAt(index)->deleteLater(); + } + if(!m_pendingJobs.isEmpty() && !m_userAborted) { startNextJob(); @@ -207,7 +220,7 @@ void ProcessingDialog::doneEncoding(void) qDebug("Running jobs: %u", m_runningThreads); - label_progress->setText(m_userAborted ? "Process aborted by user." : "Alle files completed."); + label_progress->setText(m_userAborted ? "Process was aborted by the user!" : "Alle files completed successfully."); m_progressIndicator->stop(); setCloseButtonEnabled(true); @@ -228,7 +241,23 @@ void ProcessingDialog::startNextJob(void) return; } - ProcessThread *thread = new ProcessThread(m_pendingJobs.takeFirst()); + AbstractEncoder *encoder = NULL; + + switch(m_settings->compressionEncoder()) + { + case SettingsModel::MP3Encoder: + { + MP3Encoder *mp3Encoder = new MP3Encoder(); + mp3Encoder->setBitrate(m_settings->compressionBitrate()); + mp3Encoder->setRCMode(m_settings->compressionRCMode()); + encoder = mp3Encoder; + } + break; + default: + throw "Unsupported encoder!"; + } + + ProcessThread *thread = new ProcessThread(m_pendingJobs.takeFirst(), 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); diff --git a/src/Dialog_Processing.h b/src/Dialog_Processing.h index 4a2baf16..14fd8e38 100644 --- a/src/Dialog_Processing.h +++ b/src/Dialog_Processing.h @@ -28,13 +28,14 @@ class ProgressModel; class ProcessThread; class FileListModel; class AudioFileModel; +class SettingsModel; class ProcessingDialog : public QDialog, private Ui::ProcessingDialog { Q_OBJECT public: - ProcessingDialog(FileListModel *fileListModel = NULL); + ProcessingDialog(FileListModel *fileListModel, SettingsModel *settings); ~ProcessingDialog(void); private slots: @@ -52,6 +53,7 @@ private: void ProcessingDialog::startNextJob(void); QList m_pendingJobs; + SettingsModel *m_settings; QList m_threadList; QMovie *m_progressIndicator; ProgressModel *m_progressModel; diff --git a/src/Encoder_Abstract.h b/src/Encoder_Abstract.h index 7775886b..4719b0d1 100644 --- a/src/Encoder_Abstract.h +++ b/src/Encoder_Abstract.h @@ -23,15 +23,18 @@ #include "Model_AudioFile.h" -#include +#include -class AbstractEncoder +class AbstractEncoder : public QObject { + Q_OBJECT + public: AbstractEncoder(void); ~AbstractEncoder(void); - virtual bool encode(const AudioFileModel &sourceFile, const QString &outputFile) = 0; + virtual bool encode(const AudioFileModel &sourceFile, const QString &outputFile, volatile bool *abortFlag) = 0; + virtual QString extension(void) = 0; void setBitrate(int bitrate); void setRCMode(int mode); diff --git a/src/Encoder_MP3.cpp b/src/Encoder_MP3.cpp index dfd19fa8..9050f229 100644 --- a/src/Encoder_MP3.cpp +++ b/src/Encoder_MP3.cpp @@ -43,10 +43,10 @@ MP3Encoder::~MP3Encoder(void) { } -bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputFile) +bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputFile, volatile bool *abortFlag) { const QString baseName = QFileInfo(outputFile).fileName(); - emit statusUpdated(baseName); + emit statusUpdated(0); QProcess process; process.setProcessChannelMode(QProcess::MergedChannels); @@ -87,35 +87,60 @@ bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputF return false; } + bool bTimeout = false; + bool bAborted = false; + QRegExp regExp("\\(.*(\\d+)%\\)\\|"); while(process.state() != QProcess::NotRunning) { + if(*abortFlag) + { + process.kill(); + bAborted = true; + break; + } process.waitForReadyRead(); + if(!process.bytesAvailable() && process.state() == QProcess::Running) + { + process.kill(); + qWarning("LAME process timed out <-- killing!"); + bTimeout = true; + break; + } while(process.bytesAvailable() > 0) { QByteArray line = process.readLine(); - qDebug("%s", line.constData()); - QString text = QString::fromLocal8Bit(line.constData()).simplified(); - if(regExp.lastIndexIn(line) >= 0) + QString text = QString::fromUtf8(line.constData()).simplified(); + if(regExp.lastIndexIn(text) >= 0) { - emit statusUpdated(QString("%1 [%2%]").arg(baseName, regExp.cap(1))); + bool ok = false; + int progress = regExp.cap(1).toInt(&ok); + if(ok) emit statusUpdated(progress); + } + else if(!text.isEmpty()) + { + qDebug("%s", text.toUtf8().constData()); } } } process.waitForFinished(); - if(process.state() != QProcess::NotRunning) { process.kill(); process.waitForFinished(-1); } - if(process.exitStatus() != QProcess::NormalExit) + if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit) { return false; } return true; -} \ No newline at end of file +} + +QString MP3Encoder::extension(void) +{ + return "mp3"; +} diff --git a/src/Encoder_MP3.h b/src/Encoder_MP3.h index 0822cf0f..d64d9abb 100644 --- a/src/Encoder_MP3.h +++ b/src/Encoder_MP3.h @@ -25,7 +25,7 @@ #include -class MP3Encoder : public QObject, public AbstractEncoder +class MP3Encoder : public AbstractEncoder { Q_OBJECT @@ -33,10 +33,11 @@ public: MP3Encoder(void); ~MP3Encoder(void); - virtual bool encode(const AudioFileModel &sourceFile, const QString &outputFile); + virtual bool encode(const AudioFileModel &sourceFile, const QString &outputFile, volatile bool *abortFlag); + virtual QString extension(void); signals: - void statusUpdated(const QString &text); + void statusUpdated(int progress); private: const QString m_binary; diff --git a/src/Main.cpp b/src/Main.cpp index 9abc5f5d..250f1a79 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -29,12 +29,14 @@ #include "Model_Settings.h" #include "Model_FileList.h" #include "Model_AudioFile.h" +#include "Encoder_Abstract.h" //Qt includes #include #include #include #include +#include /////////////////////////////////////////////////////////////////////////////// // Main function @@ -138,7 +140,7 @@ int lamexp_main(int argc, char* argv[]) //Show processing dialog if(bAccepted && fileListModel->rowCount() > 0) { - ProcessingDialog *processingDialog = new ProcessingDialog(fileListModel); + ProcessingDialog *processingDialog = new ProcessingDialog(fileListModel, settingsModel); processingDialog->exec(); LAMEXP_DELETE(processingDialog); } diff --git a/src/Model_FileList.cpp b/src/Model_FileList.cpp index bb58a86e..1969b24e 100644 --- a/src/Model_FileList.cpp +++ b/src/Model_FileList.cpp @@ -28,9 +28,9 @@ //////////////////////////////////////////////////////////// FileListModel::FileListModel(void) - : m_fileIcon(":/icons/page_white_cd.png") +: + m_fileIcon(":/icons/page_white_cd.png") { - m_fileList.append(AudioFileModel("C:/Music/Buckethead - Crime Slunk Scene/The Fairy and the Devil.ogg", "The Fairy and the Devil")); } FileListModel::~FileListModel(void) diff --git a/src/Model_Progress.cpp b/src/Model_Progress.cpp index 7ea749df..2b6dddc5 100644 --- a/src/Model_Progress.cpp +++ b/src/Model_Progress.cpp @@ -82,6 +82,10 @@ QVariant ProgressModel::data(const QModelIndex &index, int role) const break; } } + else if(role == Qt::TextAlignmentRole) + { + return (index.column() == 1) ? QVariant(Qt::AlignHCenter | Qt::AlignVCenter) : QVariant(); + } } return QVariant(); diff --git a/src/Model_Settings.cpp b/src/Model_Settings.cpp index e128aad6..0b7c87ff 100644 --- a/src/Model_Settings.cpp +++ b/src/Model_Settings.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include static const char *g_settingsId_versionNumber = "VersionNumber"; static const char *g_settingsId_licenseAccepted = "LicenseAccepted"; @@ -33,9 +35,12 @@ 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"; #define MAKE_GETTER(OPT,DEF) int SettingsModel::OPT(void) { return m_settings->value(g_settingsId_##OPT, DEF).toInt(); } #define MAKE_SETTER(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); } const int SettingsModel::mp3Bitrates[15] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1}; @@ -79,6 +84,10 @@ void SettingsModel::validate(void) { if(this->compressionEncoder() == SettingsModel::AACEncoder) this->compressionEncoder(SettingsModel::MP3Encoder); } + if(this->outputDir().isEmpty() || !QFileInfo(this->outputDir()).isDir()) + { + this->outputDir(QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); + } } //////////////////////////////////////////////////////////// @@ -99,3 +108,7 @@ MAKE_SETTER(compressionRCMode) MAKE_GETTER(compressionBitrate, 0) MAKE_SETTER(compressionBitrate) + +MAKE_GETTER2(outputDir, QString()) +MAKE_SETTER2(outputDir) + diff --git a/src/Model_Settings.h b/src/Model_Settings.h index 7ee7f483..23b21709 100644 --- a/src/Model_Settings.h +++ b/src/Model_Settings.h @@ -22,9 +22,12 @@ #pragma once class QSettings; +class QString; #define MAKE_GETTER_DEC(OPT) int OPT(void) #define MAKE_SETTER_DEC(OPT) void OPT(int value) +#define MAKE_GETTER_DEC2(OPT) QString OPT(void) +#define MAKE_SETTER_DEC2(OPT) void OPT(const QString &value) class SettingsModel { @@ -57,6 +60,7 @@ public: MAKE_GETTER_DEC(compressionEncoder); MAKE_GETTER_DEC(compressionRCMode); MAKE_GETTER_DEC(compressionBitrate); + MAKE_GETTER_DEC2(outputDir); //Setters @@ -65,6 +69,7 @@ public: MAKE_SETTER_DEC(compressionBitrate); MAKE_SETTER_DEC(compressionRCMode); MAKE_SETTER_DEC(compressionEncoder); + MAKE_SETTER_DEC2(outputDir); void validate(void); @@ -74,3 +79,5 @@ private: #undef MAKE_GETTER_DEC #undef MAKE_SETTER_DEC +#undef MAKE_GETTER_DEC2 +#undef MAKE_SETTER_DEC2 diff --git a/src/Thread_Process.cpp b/src/Thread_Process.cpp index ea27a84a..980be925 100644 --- a/src/Thread_Process.cpp +++ b/src/Thread_Process.cpp @@ -24,9 +24,13 @@ #include "Global.h" #include "Model_AudioFile.h" #include "Model_Progress.h" +#include "Encoder_Abstract.h" + +#include "Model_Settings.h" #include #include +#include #include #include @@ -35,16 +39,20 @@ // Constructor //////////////////////////////////////////////////////////// -ProcessThread::ProcessThread(AudioFileModel audioFile) +ProcessThread::ProcessThread(const AudioFileModel &audioFile, const QString &outputDirectory, AbstractEncoder *encoder) : m_audioFile(audioFile), + m_outputDirectory(outputDirectory), + m_encoder(encoder), m_jobId(QUuid::createUuid()), m_aborted(false) { + connect(m_encoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection); } ProcessThread::~ProcessThread(void) { + LAMEXP_DELETE(m_encoder); } void ProcessThread::run() @@ -53,27 +61,55 @@ 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); - - QUuid uuid = QUuid::createUuid(); - qsrand(uuid.data1 * uuid.data2 * uuid.data3 * uuid.data4[0] * uuid.data4[1] * uuid.data4[2] * uuid.data4[3] * uuid.data4[4] * uuid.data4[5] * uuid.data4[6] * uuid.data4[7]); - unsigned long delay = 100 + (qrand() % 150); - for(int i = 1; i <= 100; i++) + if(!QFileInfo(m_audioFile.filePath()).isFile()) { - if(m_aborted) - { - emit processStateChanged(m_jobId, "Aborted.", ProgressModel::JobFailed); - return; - } - - QThread::msleep(delay); - emit processStateChanged(m_jobId, QString("Encoding (%1%)").arg(i), ProgressModel::JobRunning); + emit processStateChanged(m_jobId, "Not found!", ProgressModel::JobFailed); + return; } - emit processStateChanged(m_jobId, "Done (100%)", ProgressModel::JobComplete); + QString outFileName = generateOutFileName(); + bool bSuccess = m_encoder->encode(m_audioFile, outFileName, &m_aborted); + + if(bSuccess) + { + bSuccess = QFileInfo(outFileName).exists(); + } + + emit processStateChanged(m_jobId, (bSuccess ? "Done." : (m_aborted ? "Aborted!" : "Failed!")), (bSuccess ? ProgressModel::JobComplete : ProgressModel::JobFailed)); qDebug("Process thread is done."); } +//////////////////////////////////////////////////////////// +// SLOTS +//////////////////////////////////////////////////////////// + +void ProcessThread::handleUpdate(int progress) +{ + emit processStateChanged(m_jobId, QString("Encoding (%1%)").arg(QString::number(progress)), ProgressModel::JobRunning); +} + +//////////////////////////////////////////////////////////// +// PRIVAE FUNCTIONS +//////////////////////////////////////////////////////////// + +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"); + + while(QFileInfo(outFileName).exists()) + { + outFileName = QString("%1/%2 (%3).%4").arg(targetDir, baseName, QString::number(++n), m_encoder->extension()); + } + + return outFileName; +} + //////////////////////////////////////////////////////////// // EVENTS //////////////////////////////////////////////////////////// diff --git a/src/Thread_Process.h b/src/Thread_Process.h index 141001fa..59d01938 100644 --- a/src/Thread_Process.h +++ b/src/Thread_Process.h @@ -25,24 +25,32 @@ #include #include "Model_AudioFile.h" +#include "Encoder_Abstract.h" class ProcessThread: public QThread { Q_OBJECT public: - ProcessThread(AudioFileModel audioFile); + ProcessThread(const AudioFileModel &audioFile, const QString &outputDirectory, AbstractEncoder *encoder); ~ProcessThread(void); void run(); void abort() { m_aborted = true; } QUuid getId() { return m_jobId; } +private slots: + void handleUpdate(int progress); + signals: void processStateInitialized(const QUuid &jobId, const QString &jobName, const QString &jobInitialStatus, int jobInitialState); void processStateChanged(const QUuid &jobId, const QString &newStatus, int newState); private: + QString generateOutFileName(void); + const QUuid m_jobId; AudioFileModel m_audioFile; + AbstractEncoder *m_encoder; + const QString m_outputDirectory; volatile bool m_aborted; };