Actually use selected encoder in progress dialog + forward output dir.

This commit is contained in:
LoRd_MuldeR 2010-11-20 02:14:22 +01:00
parent 28a926b820
commit 1633489aaf
16 changed files with 252 additions and 77 deletions

View File

@ -595,6 +595,36 @@
<File <File
RelativePath=".\src\Encoder_Abstract.h" RelativePath=".\src\Encoder_Abstract.h"
> >
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="MOC &quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot;"
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -o &quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
Outputs="&quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot;"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="MOC &quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot;"
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -o &quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
Outputs="&quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot;"
/>
</FileConfiguration>
<FileConfiguration
Name="Release_Static|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="MOC &quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot;"
CommandLine="&quot;$(QTDIR)\bin\moc.exe&quot; -o &quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;"
Outputs="&quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot;"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\src\Encoder_MP3.h" RelativePath=".\src\Encoder_MP3.h"
@ -960,6 +990,10 @@
RelativePath=".\tmp\MOC_Dialog_WorkingBanner.cpp" RelativePath=".\tmp\MOC_Dialog_WorkingBanner.cpp"
> >
</File> </File>
<File
RelativePath=".\tmp\MOC_Encoder_Abstract.cpp"
>
</File>
<File <File
RelativePath=".\tmp\MOC_Encoder_MP3.cpp" RelativePath=".\tmp\MOC_Encoder_MP3.cpp"
> >

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 44 #define VER_LAMEXP_BUILD 49
#define VER_LAMEXP_SUFFIX TechPreview #define VER_LAMEXP_SUFFIX TechPreview
/* /*

View File

@ -114,12 +114,18 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
sourceFileView->setModel(m_fileListModel); sourceFileView->setModel(m_fileListModel);
sourceFileView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); sourceFileView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
sourceFileView->horizontalHeader()->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(buttonAddFiles, SIGNAL(clicked()), this, SLOT(addFilesButtonClicked()));
connect(buttonRemoveFile, SIGNAL(clicked()), this, SLOT(removeFileButtonClicked())); connect(buttonRemoveFile, SIGNAL(clicked()), this, SLOT(removeFileButtonClicked()));
connect(buttonClearFiles, SIGNAL(clicked()), this, SLOT(clearFilesButtonClicked())); connect(buttonClearFiles, SIGNAL(clicked()), this, SLOT(clearFilesButtonClicked()));
connect(buttonFileUp, SIGNAL(clicked()), this, SLOT(fileUpButtonClicked())); connect(buttonFileUp, SIGNAL(clicked()), this, SLOT(fileUpButtonClicked()));
connect(buttonFileDown, SIGNAL(clicked()), this, SLOT(fileDownButtonClicked())); connect(buttonFileDown, SIGNAL(clicked()), this, SLOT(fileDownButtonClicked()));
connect(buttonShowDetails, SIGNAL(clicked()), this, SLOT(showDetailsButtonClicked())); 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 //Setup "Output" tab
m_fileSystemModel = new QFileSystemModel(); m_fileSystemModel = new QFileSystemModel();
@ -133,7 +139,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
outputFolderView->setHeaderHidden(true); outputFolderView->setHeaderHidden(true);
outputFolderView->setAnimated(true); outputFolderView->setAnimated(true);
connect(outputFolderView, SIGNAL(clicked(QModelIndex)), this, SLOT(outputFolderViewClicked(QModelIndex))); 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()); outputFolderViewClicked(outputFolderView->currentIndex());
connect(buttonMakeFolder, SIGNAL(clicked()), this, SLOT(makeFolderButtonClicked())); connect(buttonMakeFolder, SIGNAL(clicked()), this, SLOT(makeFolderButtonClicked()));
connect(buttonGotoHome, SIGNAL(clicked()), SLOT(gotoHomeFolderButtonClicked())); connect(buttonGotoHome, SIGNAL(clicked()), SLOT(gotoHomeFolderButtonClicked()));
@ -269,6 +275,7 @@ MainWindow::~MainWindow(void)
LAMEXP_DELETE(m_delayedFileTimer); LAMEXP_DELETE(m_delayedFileTimer);
LAMEXP_DELETE(m_metaInfoModel); LAMEXP_DELETE(m_metaInfoModel);
LAMEXP_DELETE(m_encoderButtonGroup); LAMEXP_DELETE(m_encoderButtonGroup);
LAMEXP_DELETE(m_encoderButtonGroup);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -310,8 +317,10 @@ void MainWindow::addFiles(const QStringList &files)
void MainWindow::showEvent(QShowEvent *event) void MainWindow::showEvent(QShowEvent *event)
{ {
QTimer::singleShot(0, this, SLOT(windowShown()));
m_accepted = false; m_accepted = false;
m_dropNoteLabel->setGeometry(0, 0, sourceFileView->width(), sourceFileView->height());
modelReset();
QTimer::singleShot(0, this, SLOT(windowShown()));
} }
void MainWindow::dragEnterEvent(QDragEnterEvent *event) 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 // Slots
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -450,8 +465,6 @@ void MainWindow::aboutButtonClicked(void)
LAMEXP_DELETE(aboutBox); LAMEXP_DELETE(aboutBox);
} }
#define IF_UNICODE(STR) if(_stricmp(STR.toUtf8().constData(),QString::fromLocal8Bit(STR.toLocal8Bit()).toUtf8().constData()))
/* /*
* Encode button * Encode button
*/ */
@ -459,46 +472,22 @@ void MainWindow::encodeButtonClicked(void)
{ {
ABORT_IF_BUSY; 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) 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); tabWidget->setCurrentIndex(3);
return; return;
} }
m_accepted = true; m_accepted = true;
close(); 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); QString selectedDir = m_fileSystemModel->filePath(index);
if(selectedDir.length() < 3) selectedDir.append(QDir::separator()); if(selectedDir.length() < 3) selectedDir.append(QDir::separator());
outputFolderLabel->setText(selectedDir); outputFolderLabel->setText(selectedDir);
m_settings->outputDir(selectedDir);
} }
/* /*
@ -1060,3 +1050,19 @@ void MainWindow::updateBitrate(int value)
break; 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);
}

View File

@ -34,6 +34,7 @@ class MetaInfoModel;
class SettingsModel; class SettingsModel;
class QButtonGroup; class QButtonGroup;
class FileListModel; class FileListModel;
class AbstractEncoder;
class MainWindow: public QMainWindow, private Ui::MainWindow class MainWindow: public QMainWindow, private Ui::MainWindow
{ {
@ -75,12 +76,15 @@ private slots:
void updateEncoder(int id); void updateEncoder(int id);
void updateRCMode(int id); void updateRCMode(int id);
void updateBitrate(int value); void updateBitrate(int value);
void rowsChanged(const QModelIndex &parent, int start, int end);
void modelReset(void);
protected: protected:
void showEvent(QShowEvent *event); void showEvent(QShowEvent *event);
void dragEnterEvent(QDragEnterEvent *event); void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event); void dropEvent(QDropEvent *event);
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
void resizeEvent(QResizeEvent *event);
private: private:
void addFiles(const QStringList &files); void addFiles(const QStringList &files);
@ -99,4 +103,5 @@ private:
AudioFileModel *m_metaData; AudioFileModel *m_metaData;
MetaInfoModel *m_metaInfoModel; MetaInfoModel *m_metaInfoModel;
SettingsModel *m_settings; SettingsModel *m_settings;
QLabel *m_dropNoteLabel;
}; };

View File

@ -24,7 +24,9 @@
#include "Global.h" #include "Global.h"
#include "Model_FileList.h" #include "Model_FileList.h"
#include "Model_Progress.h" #include "Model_Progress.h"
#include "Model_Settings.h"
#include "Thread_Process.h" #include "Thread_Process.h"
#include "Encoder_MP3.h"
#include <QApplication> #include <QApplication>
#include <QRect> #include <QRect>
@ -41,7 +43,9 @@
// Constructor // Constructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
ProcessingDialog::ProcessingDialog(FileListModel *fileListModel) ProcessingDialog::ProcessingDialog(FileListModel *fileListModel, SettingsModel *settings)
:
m_settings(settings)
{ {
//Init the dialog, from the .ui file //Init the dialog, from the .ui file
setupUi(this); setupUi(this);
@ -103,7 +107,10 @@ ProcessingDialog::~ProcessingDialog(void)
while(!m_threadList.isEmpty()) 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--; m_runningThreads--;
progressBar->setValue(progressBar->value() + 1); 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<ProcessThread*>(QWidget::sender()));
if(index >= 0)
{
m_threadList.takeAt(index)->deleteLater();
}
if(!m_pendingJobs.isEmpty() && !m_userAborted) if(!m_pendingJobs.isEmpty() && !m_userAborted)
{ {
startNextJob(); startNextJob();
@ -207,7 +220,7 @@ void ProcessingDialog::doneEncoding(void)
qDebug("Running jobs: %u", m_runningThreads); 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(); m_progressIndicator->stop();
setCloseButtonEnabled(true); setCloseButtonEnabled(true);
@ -228,7 +241,23 @@ void ProcessingDialog::startNextJob(void)
return; 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); m_threadList.append(thread);
connect(thread, SIGNAL(finished()), this, SLOT(doneEncoding()), Qt::QueuedConnection); 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); connect(thread, SIGNAL(processStateInitialized(QUuid,QString,QString,int)), m_progressModel, SLOT(addJob(QUuid,QString,QString,int)), Qt::QueuedConnection);

View File

@ -28,13 +28,14 @@ class ProgressModel;
class ProcessThread; class ProcessThread;
class FileListModel; class FileListModel;
class AudioFileModel; class AudioFileModel;
class SettingsModel;
class ProcessingDialog : public QDialog, private Ui::ProcessingDialog class ProcessingDialog : public QDialog, private Ui::ProcessingDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
ProcessingDialog(FileListModel *fileListModel = NULL); ProcessingDialog(FileListModel *fileListModel, SettingsModel *settings);
~ProcessingDialog(void); ~ProcessingDialog(void);
private slots: private slots:
@ -52,6 +53,7 @@ private:
void ProcessingDialog::startNextJob(void); void ProcessingDialog::startNextJob(void);
QList<AudioFileModel> m_pendingJobs; QList<AudioFileModel> m_pendingJobs;
SettingsModel *m_settings;
QList<ProcessThread*> m_threadList; QList<ProcessThread*> m_threadList;
QMovie *m_progressIndicator; QMovie *m_progressIndicator;
ProgressModel *m_progressModel; ProgressModel *m_progressModel;

View File

@ -23,15 +23,18 @@
#include "Model_AudioFile.h" #include "Model_AudioFile.h"
#include <QString> #include <QObject>
class AbstractEncoder class AbstractEncoder : public QObject
{ {
Q_OBJECT
public: public:
AbstractEncoder(void); AbstractEncoder(void);
~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 setBitrate(int bitrate);
void setRCMode(int mode); void setRCMode(int mode);

View File

@ -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(); const QString baseName = QFileInfo(outputFile).fileName();
emit statusUpdated(baseName); emit statusUpdated(0);
QProcess process; QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels); process.setProcessChannelMode(QProcess::MergedChannels);
@ -87,35 +87,60 @@ bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputF
return false; return false;
} }
bool bTimeout = false;
bool bAborted = false;
QRegExp regExp("\\(.*(\\d+)%\\)\\|"); QRegExp regExp("\\(.*(\\d+)%\\)\\|");
while(process.state() != QProcess::NotRunning) while(process.state() != QProcess::NotRunning)
{ {
if(*abortFlag)
{
process.kill();
bAborted = true;
break;
}
process.waitForReadyRead(); process.waitForReadyRead();
if(!process.bytesAvailable() && process.state() == QProcess::Running)
{
process.kill();
qWarning("LAME process timed out <-- killing!");
bTimeout = true;
break;
}
while(process.bytesAvailable() > 0) while(process.bytesAvailable() > 0)
{ {
QByteArray line = process.readLine(); QByteArray line = process.readLine();
qDebug("%s", line.constData()); QString text = QString::fromUtf8(line.constData()).simplified();
QString text = QString::fromLocal8Bit(line.constData()).simplified(); if(regExp.lastIndexIn(text) >= 0)
if(regExp.lastIndexIn(line) >= 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(); process.waitForFinished();
if(process.state() != QProcess::NotRunning) if(process.state() != QProcess::NotRunning)
{ {
process.kill(); process.kill();
process.waitForFinished(-1); process.waitForFinished(-1);
} }
if(process.exitStatus() != QProcess::NormalExit) if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit)
{ {
return false; return false;
} }
return true; return true;
} }
QString MP3Encoder::extension(void)
{
return "mp3";
}

View File

@ -25,7 +25,7 @@
#include <QObject> #include <QObject>
class MP3Encoder : public QObject, public AbstractEncoder class MP3Encoder : public AbstractEncoder
{ {
Q_OBJECT Q_OBJECT
@ -33,10 +33,11 @@ public:
MP3Encoder(void); MP3Encoder(void);
~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: signals:
void statusUpdated(const QString &text); void statusUpdated(int progress);
private: private:
const QString m_binary; const QString m_binary;

View File

@ -29,12 +29,14 @@
#include "Model_Settings.h" #include "Model_Settings.h"
#include "Model_FileList.h" #include "Model_FileList.h"
#include "Model_AudioFile.h" #include "Model_AudioFile.h"
#include "Encoder_Abstract.h"
//Qt includes //Qt includes
#include <QApplication> #include <QApplication>
#include <QMessageBox> #include <QMessageBox>
#include <QDate> #include <QDate>
#include <QMutex> #include <QMutex>
#include <QDir>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Main function // Main function
@ -138,7 +140,7 @@ int lamexp_main(int argc, char* argv[])
//Show processing dialog //Show processing dialog
if(bAccepted && fileListModel->rowCount() > 0) if(bAccepted && fileListModel->rowCount() > 0)
{ {
ProcessingDialog *processingDialog = new ProcessingDialog(fileListModel); ProcessingDialog *processingDialog = new ProcessingDialog(fileListModel, settingsModel);
processingDialog->exec(); processingDialog->exec();
LAMEXP_DELETE(processingDialog); LAMEXP_DELETE(processingDialog);
} }

View File

@ -28,9 +28,9 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
FileListModel::FileListModel(void) 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) FileListModel::~FileListModel(void)

View File

@ -82,6 +82,10 @@ QVariant ProgressModel::data(const QModelIndex &index, int role) const
break; break;
} }
} }
else if(role == Qt::TextAlignmentRole)
{
return (index.column() == 1) ? QVariant(Qt::AlignHCenter | Qt::AlignVCenter) : QVariant();
}
} }
return QVariant(); return QVariant();

View File

@ -26,6 +26,8 @@
#include <QSettings> #include <QSettings>
#include <QDesktopServices> #include <QDesktopServices>
#include <QApplication> #include <QApplication>
#include <QString>
#include <QFileInfo>
static const char *g_settingsId_versionNumber = "VersionNumber"; static const char *g_settingsId_versionNumber = "VersionNumber";
static const char *g_settingsId_licenseAccepted = "LicenseAccepted"; 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_compressionEncoder = "Compression/Encoder";
static const char *g_settingsId_compressionRCMode = "Compression/RCMode"; static const char *g_settingsId_compressionRCMode = "Compression/RCMode";
static const char *g_settingsId_compressionBitrate = "Compression/Bitrate"; 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_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_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}; 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->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_GETTER(compressionBitrate, 0)
MAKE_SETTER(compressionBitrate) MAKE_SETTER(compressionBitrate)
MAKE_GETTER2(outputDir, QString())
MAKE_SETTER2(outputDir)

View File

@ -22,9 +22,12 @@
#pragma once #pragma once
class QSettings; class QSettings;
class QString;
#define MAKE_GETTER_DEC(OPT) int OPT(void) #define MAKE_GETTER_DEC(OPT) int OPT(void)
#define MAKE_SETTER_DEC(OPT) void OPT(int value) #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 class SettingsModel
{ {
@ -57,6 +60,7 @@ public:
MAKE_GETTER_DEC(compressionEncoder); MAKE_GETTER_DEC(compressionEncoder);
MAKE_GETTER_DEC(compressionRCMode); MAKE_GETTER_DEC(compressionRCMode);
MAKE_GETTER_DEC(compressionBitrate); MAKE_GETTER_DEC(compressionBitrate);
MAKE_GETTER_DEC2(outputDir);
//Setters //Setters
@ -65,6 +69,7 @@ public:
MAKE_SETTER_DEC(compressionBitrate); MAKE_SETTER_DEC(compressionBitrate);
MAKE_SETTER_DEC(compressionRCMode); MAKE_SETTER_DEC(compressionRCMode);
MAKE_SETTER_DEC(compressionEncoder); MAKE_SETTER_DEC(compressionEncoder);
MAKE_SETTER_DEC2(outputDir);
void validate(void); void validate(void);
@ -74,3 +79,5 @@ private:
#undef MAKE_GETTER_DEC #undef MAKE_GETTER_DEC
#undef MAKE_SETTER_DEC #undef MAKE_SETTER_DEC
#undef MAKE_GETTER_DEC2
#undef MAKE_SETTER_DEC2

View File

@ -24,9 +24,13 @@
#include "Global.h" #include "Global.h"
#include "Model_AudioFile.h" #include "Model_AudioFile.h"
#include "Model_Progress.h" #include "Model_Progress.h"
#include "Encoder_Abstract.h"
#include "Model_Settings.h"
#include <QUuid> #include <QUuid>
#include <QFileInfo> #include <QFileInfo>
#include <QDir>
#include <limits.h> #include <limits.h>
#include <time.h> #include <time.h>
@ -35,16 +39,20 @@
// Constructor // Constructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
ProcessThread::ProcessThread(AudioFileModel audioFile) ProcessThread::ProcessThread(const AudioFileModel &audioFile, const QString &outputDirectory, AbstractEncoder *encoder)
: :
m_audioFile(audioFile), m_audioFile(audioFile),
m_outputDirectory(outputDirectory),
m_encoder(encoder),
m_jobId(QUuid::createUuid()), m_jobId(QUuid::createUuid()),
m_aborted(false) m_aborted(false)
{ {
connect(m_encoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection);
} }
ProcessThread::~ProcessThread(void) ProcessThread::~ProcessThread(void)
{ {
LAMEXP_DELETE(m_encoder);
} }
void ProcessThread::run() void ProcessThread::run()
@ -53,27 +61,55 @@ void ProcessThread::run()
qDebug("Process thread %s has started.", m_jobId.toString().toLatin1().constData()); qDebug("Process thread %s has started.", m_jobId.toString().toLatin1().constData());
emit processStateInitialized(m_jobId, QFileInfo(m_audioFile.filePath()).fileName(), "Starting...", ProgressModel::JobRunning); 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, "Not found!", ProgressModel::JobFailed);
{ return;
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, "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."); 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 // EVENTS
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -25,24 +25,32 @@
#include <QUuid> #include <QUuid>
#include "Model_AudioFile.h" #include "Model_AudioFile.h"
#include "Encoder_Abstract.h"
class ProcessThread: public QThread class ProcessThread: public QThread
{ {
Q_OBJECT Q_OBJECT
public: public:
ProcessThread(AudioFileModel audioFile); ProcessThread(const AudioFileModel &audioFile, const QString &outputDirectory, AbstractEncoder *encoder);
~ProcessThread(void); ~ProcessThread(void);
void run(); void run();
void abort() { m_aborted = true; } void abort() { m_aborted = true; }
QUuid getId() { return m_jobId; } QUuid getId() { return m_jobId; }
private slots:
void handleUpdate(int progress);
signals: signals:
void processStateInitialized(const QUuid &jobId, const QString &jobName, const QString &jobInitialStatus, int jobInitialState); void processStateInitialized(const QUuid &jobId, const QString &jobName, const QString &jobInitialStatus, int jobInitialState);
void processStateChanged(const QUuid &jobId, const QString &newStatus, int newState); void processStateChanged(const QUuid &jobId, const QString &newStatus, int newState);
private: private:
QString generateOutFileName(void);
const QUuid m_jobId; const QUuid m_jobId;
AudioFileModel m_audioFile; AudioFileModel m_audioFile;
AbstractEncoder *m_encoder;
const QString m_outputDirectory;
volatile bool m_aborted; volatile bool m_aborted;
}; };