OSDN Git Service

Create playlist file + serialize filename generation, just to be sure.
authorlordmulder <mulder2@gmx.de>
Sat, 20 Nov 2010 21:14:10 +0000 (22:14 +0100)
committerlordmulder <mulder2@gmx.de>
Sat, 20 Nov 2010 21:14:10 +0000 (22:14 +0100)
src/Config.h
src/Dialog_MainWindow.cpp
src/Dialog_MainWindow.h
src/Dialog_Processing.cpp
src/Dialog_Processing.h
src/Main.cpp
src/Model_Settings.cpp
src/Model_Settings.h
src/Thread_Process.cpp
src/Thread_Process.h

index a88bd02..86ffafc 100644 (file)
@@ -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                               54
+#define VER_LAMEXP_BUILD                               57
 #define VER_LAMEXP_SUFFIX                              TechPreview
 
 /*
index 354e16b..55bb4c7 100644 (file)
 #include <Windows.h>
 
 //Helper macros
-#define ABORT_IF_BUSY \
-if(m_banner->isVisible() || m_delayedFileTimer->isActive()) \
-{ \
-       MessageBeep(MB_ICONEXCLAMATION); \
-       return; \
-}
+#define ABORT_IF_BUSY if(m_banner->isVisible() || m_delayedFileTimer->isActive()) { MessageBeep(MB_ICONEXCLAMATION); return; }
+#define SET_TEXT_COLOR(WIDGET,COLOR) { QPalette _palette = WIDGET->palette(); _palette.setColor(QPalette::WindowText, COLOR); WIDGET->setPalette(_palette); }
+#define SET_FONT_BOLD(WIDGET,BOLD) { QFont _font = WIDGET->font(); _font.setBold(BOLD); WIDGET->setFont(_font); }
 #define LINK(URL) QString("<a href=\"%1\">%2</a>").arg(URL).arg(URL)
 
+
 //Helper class
 class Index: public QObjectUserData
 {
@@ -86,7 +84,8 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
        m_fileListModel(fileListModel),
        m_metaData(metaInfo),
        m_settings(settingsModel),
-       m_accepted(false)
+       m_accepted(false),
+       m_firstTimeShown(true)
 {
        //Init the dialog, from the .ui file
        setupUi(this);
@@ -117,6 +116,8 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
        m_dropNoteLabel = new QLabel(sourceFileView);
        m_dropNoteLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        m_dropNoteLabel->setText("» You can drop in audio files here! «");
+       SET_FONT_BOLD(m_dropNoteLabel, true);
+       SET_TEXT_COLOR(m_dropNoteLabel, Qt::darkGray);
        connect(buttonAddFiles, SIGNAL(clicked()), this, SLOT(addFilesButtonClicked()));
        connect(buttonRemoveFile, SIGNAL(clicked()), this, SLOT(removeFileButtonClicked()));
        connect(buttonClearFiles, SIGNAL(clicked()), this, SLOT(clearFilesButtonClicked()));
@@ -154,10 +155,12 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
        metaDataView->verticalHeader()->hide();
        metaDataView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
        while(writeMetaDataCheckBox->isChecked() != m_settings->writeMetaTags()) writeMetaDataCheckBox->click();
+       while(generatePlaylistCheckBox->isChecked() != m_settings->createPlaylist()) generatePlaylistCheckBox->click();
        connect(buttonEditMeta, SIGNAL(clicked()), this, SLOT(editMetaButtonClicked()));
        connect(buttonClearMeta, SIGNAL(clicked()), this, SLOT(clearMetaButtonClicked()));
        connect(writeMetaDataCheckBox, SIGNAL(clicked()), this, SLOT(metaTagsEnabledChanged()));
-       
+       connect(generatePlaylistCheckBox, SIGNAL(clicked()), this, SLOT(playlistEnabledChanged()));
+
        //Setup "Compression" tab
        m_encoderButtonGroup = new QButtonGroup(this);
        m_encoderButtonGroup->addButton(radioButtonEncoderMP3, SettingsModel::MP3Encoder);
@@ -322,7 +325,13 @@ void MainWindow::showEvent(QShowEvent *event)
        m_accepted = false;
        m_dropNoteLabel->setGeometry(0, 0, sourceFileView->width(), sourceFileView->height());
        modelReset();
-       QTimer::singleShot(0, this, SLOT(windowShown()));
+       tabWidget->setCurrentIndex(0);
+
+       if(m_firstTimeShown)
+       {
+               m_firstTimeShown = false;
+               QTimer::singleShot(0, this, SLOT(windowShown()));
+       }
 }
 
 void MainWindow::dragEnterEvent(QDragEnterEvent *event)
@@ -1076,3 +1085,11 @@ void MainWindow::metaTagsEnabledChanged(void)
 {
        m_settings->writeMetaTags(writeMetaDataCheckBox->isChecked());
 }
+
+/*
+ * Playlist enabled changed
+ */
+void MainWindow::playlistEnabledChanged(void)
+{
+       m_settings->createPlaylist(generatePlaylistCheckBox->isChecked());
+}
index 825db17..49a4d84 100644 (file)
@@ -79,6 +79,7 @@ private slots:
        void rowsChanged(const QModelIndex &parent, int start, int end);
        void modelReset(void);
        void metaTagsEnabledChanged(void);
+       void playlistEnabledChanged(void);
 
 protected:
        void showEvent(QShowEvent *event);
@@ -91,6 +92,7 @@ private:
        void addFiles(const QStringList &files);
 
        bool m_accepted;
+       bool m_firstTimeShown;
        FileListModel *m_fileListModel;
        QFileSystemModel *m_fileSystemModel;
        QActionGroup *m_tabActionGroup;
index c4a3ef0..6476cb0 100644 (file)
@@ -37,6 +37,9 @@
 #include <QCloseEvent>
 #include <QDesktopServices>
 #include <QUrl>
+#include <QUuid>
+#include <QFileInfo>
+
 #include <Windows.h>
 
 ////////////////////////////////////////////////////////////
@@ -173,6 +176,7 @@ void ProcessingDialog::initEncoding(void)
        m_runningThreads = 0;
        m_currentFile = 0;
        m_userAborted = false;
+       m_playList.clear();
        
        label_progress->setText("Encoding files, please wait...");
        m_progressIndicator->start();
@@ -224,6 +228,13 @@ void ProcessingDialog::doneEncoding(void)
 
        qDebug("Running jobs: %u", m_runningThreads);
 
+       if(!m_userAborted && m_settings->createPlaylist() && !m_settings->outputDir().isEmpty())
+       {
+               label_progress->setText("Creatig the play list, please wait...");
+               QApplication::processEvents();
+               writePlayList();
+       }
+       
        label_progress->setText(m_userAborted ? "Process was aborted by the user!" : "Alle files completed successfully.");
        m_progressIndicator->stop();
 
@@ -234,6 +245,14 @@ void ProcessingDialog::doneEncoding(void)
        progressBar->setValue(100);
 }
 
+void ProcessingDialog::processFinished(const QUuid &jobId, const QString &outFileName, bool success)
+{
+       if(success)
+       {
+               m_playList.append(outFileName);
+       }
+}
+
 ////////////////////////////////////////////////////////////
 // Private Functions
 ////////////////////////////////////////////////////////////
@@ -268,10 +287,43 @@ void ProcessingDialog::startNextJob(void)
        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(processStateChanged(QUuid,QString,int)), m_progressModel, SLOT(updateJob(QUuid,QString,int)), Qt::QueuedConnection);
+       connect(thread, SIGNAL(processStateFinished(QUuid,QString,bool)), this, SLOT(processFinished(QUuid,QString,bool)), Qt::QueuedConnection);
        m_runningThreads++;
        thread->start();
 }
 
+void ProcessingDialog::writePlayList(void)
+{
+       QString playListName = (m_metaInfo->fileAlbum().isEmpty() ? "Playlist" : m_metaInfo->fileAlbum());
+
+       const static char *invalidChars = "\\/:*?\"<>|";
+       for(int i = 0; invalidChars[i]; i++)
+       {
+               playListName.replace(invalidChars[i], ' ');
+               playListName = playListName.simplified();
+       }
+       
+       QString playListFile = QString("%1/%2.m3u").arg(m_settings->outputDir(), playListName);
+
+       int counter = 1;
+       while(QFileInfo(playListFile).exists())
+       {
+               playListFile = QString("%1/%2 (%3).m3u").arg(m_settings->outputDir(), playListName, QString::number(++counter));
+       }
+       
+       QFile playList(playListFile);
+       if(playList.open(QIODevice::WriteOnly))
+       {
+               playList.write("#EXTM3U\r\n");
+               for(int i = 0; i < m_playList.count(); i++)
+               {
+                       playList.write(QFileInfo(m_playList.at(i)).fileName().toUtf8().constData());
+                       playList.write("\r\n");
+               }
+               playList.close();
+       }
+}
+
 AudioFileModel ProcessingDialog::updateMetaInfo(const AudioFileModel &audioFile)
 {
        if(!m_settings->writeMetaTags())
index 3a5a736..fb35232 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "../tmp/UIC_ProcessingDialog.h"
 
+#include <QUuid>
+
 class QMovie;
 class ProgressModel;
 class ProcessThread;
@@ -42,6 +44,7 @@ private slots:
        void initEncoding(void);
        void doneEncoding(void);
        void abortEncoding(void);
+       void processFinished(const QUuid &jobId, const QString &outFileName, bool success);
 
 protected:
        void showEvent(QShowEvent *event);
@@ -52,7 +55,7 @@ private:
        void setCloseButtonEnabled(bool enabled);
        void startNextJob(void);
        AudioFileModel updateMetaInfo(const AudioFileModel &audioFile);
-
+       void writePlayList(void);
        
        QList<AudioFileModel> m_pendingJobs;
        SettingsModel *m_settings;
@@ -60,6 +63,7 @@ private:
        QList<ProcessThread*> m_threadList;
        QMovie *m_progressIndicator;
        ProgressModel *m_progressModel;
+       QStringList m_playList;
        unsigned int m_runningThreads;
        unsigned int m_currentFile;
        bool m_userAborted;
index a4b4a71..30c3c8f 100644 (file)
@@ -52,7 +52,7 @@ int lamexp_main(int argc, char* argv[])
        
        //Print version info
        qDebug("LameXP - Audio Encoder Front-End");
-       qDebug("Version %d.%02d %s, Build %d [%s], MSVC compiler v%02d.%02d", lamexp_version_major(), lamexp_version_minor(), lamexp_version_release(), lamexp_version_build(), lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(), _MSC_VER / 100, _MSC_VER % 100);
+       qDebug("Version %d.%02d %s, Build %d [%s], compiled with %s", lamexp_version_major(), lamexp_version_minor(), lamexp_version_release(), lamexp_version_build(), lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(), lamexp_version_compiler());
        qDebug("Copyright (C) 2004-%04d LoRd_MuldeR <MuldeR2@GMX.de>\n", max(lamexp_version_date().year(),QDate::currentDate().year()));
        
        //print license info
@@ -65,10 +65,10 @@ int lamexp_main(int argc, char* argv[])
        
        //Detect CPU capabilities
        lamexp_cpu_t cpuFeatures = lamexp_detect_cpu_features();
-       qDebug("CPU brand string:  %s", cpuFeatures.brand);
-       qDebug("CPU signature:     Family: %d, Model: %d, Stepping: %d", cpuFeatures.family, cpuFeatures.model, cpuFeatures.stepping);
-       qDebug("CPU capabilities:  MMX: %s, SSE: %s, SSE2: %s, SSE3: %s, SSSE3: %s, x64: %s", LAMEXP_BOOL(cpuFeatures.mmx), LAMEXP_BOOL(cpuFeatures.sse), LAMEXP_BOOL(cpuFeatures.sse2), LAMEXP_BOOL(cpuFeatures.sse3), LAMEXP_BOOL(cpuFeatures.ssse3), LAMEXP_BOOL(cpuFeatures.x64));
-       qDebug("CPU no. of cores:  %d\n", cpuFeatures.count);
+       qDebug("CPU brand string  :  %s", cpuFeatures.brand);
+       qDebug("   CPU signature  :  Family: %d, Model: %d, Stepping: %d", cpuFeatures.family, cpuFeatures.model, cpuFeatures.stepping);
+       qDebug("CPU capabilities  :  MMX: %s, SSE: %s, SSE2: %s, SSE3: %s, SSSE3: %s, x64: %s", LAMEXP_BOOL(cpuFeatures.mmx), LAMEXP_BOOL(cpuFeatures.sse), LAMEXP_BOOL(cpuFeatures.sse2), LAMEXP_BOOL(cpuFeatures.sse3), LAMEXP_BOOL(cpuFeatures.ssse3), LAMEXP_BOOL(cpuFeatures.x64));
+       qDebug("CPU no. of cores  :  %d\n", cpuFeatures.count);
        
        //Initialize Qt
        lamexp_init_qt(argc, argv);
@@ -128,14 +128,16 @@ int lamexp_main(int argc, char* argv[])
        SplashScreen::showSplash(poInitializationThread);
        LAMEXP_DELETE(poInitializationThread);
 
-       //Show main window
+       //Create main window
+       MainWindow *poMainWindow = new MainWindow(fileListModel, metaInfo, settingsModel);
+       
+       //Main application loop
        while(bAccepted)
        {
-               MainWindow *poMainWindow = new MainWindow(fileListModel, metaInfo, settingsModel);
+               //Show main window
                poMainWindow->show();
                iResult = QApplication::instance()->exec();
                bAccepted = poMainWindow->isAccepted();
-               LAMEXP_DELETE(poMainWindow);
 
                //Show processing dialog
                if(bAccepted && fileListModel->rowCount() > 0)
@@ -147,6 +149,7 @@ int lamexp_main(int argc, char* argv[])
        }
        
        //Free models
+       LAMEXP_DELETE(poMainWindow);
        LAMEXP_DELETE(fileListModel);
        LAMEXP_DELETE(metaInfo);
        LAMEXP_DELETE(settingsModel);
index 08a05e9..4b272ae 100644 (file)
@@ -37,6 +37,7 @@ 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_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); }
@@ -109,7 +110,7 @@ MAKE_SETTER1(compressionEncoder)
 MAKE_GETTER1(compressionRCMode, 0)
 MAKE_SETTER1(compressionRCMode)
 
-MAKE_GETTER1(compressionBitrate, 0)
+MAKE_GETTER1(compressionBitrate, 7)
 MAKE_SETTER1(compressionBitrate)
 
 MAKE_GETTER2(outputDir, QString())
@@ -117,3 +118,6 @@ MAKE_SETTER2(outputDir)
 
 MAKE_GETTER3(writeMetaTags, true)
 MAKE_SETTER3(writeMetaTags)
+
+MAKE_GETTER3(createPlaylist, true)
+MAKE_SETTER3(createPlaylist)
index 02549df..c5ed184 100644 (file)
@@ -64,6 +64,7 @@ public:
        MAKE_GETTER_DEC1(compressionBitrate);
        MAKE_GETTER_DEC2(outputDir);
        MAKE_GETTER_DEC3(writeMetaTags);
+       MAKE_GETTER_DEC3(createPlaylist);
 
        //Setters
        MAKE_SETTER_DEC1(licenseAccepted);
@@ -73,6 +74,7 @@ public:
        MAKE_SETTER_DEC1(compressionEncoder);
        MAKE_SETTER_DEC2(outputDir);
        MAKE_SETTER_DEC3(writeMetaTags);
+       MAKE_SETTER_DEC3(createPlaylist);
 
        void validate(void);
 
index 980be92..38101aa 100644 (file)
 #include <QUuid>
 #include <QFileInfo>
 #include <QDir>
+#include <QMutex>
+#include <QMutexLocker>
 
 #include <limits.h>
 #include <time.h>
 
+QMutex *ProcessThread::m_mutex_genFileName = NULL;
+
 ////////////////////////////////////////////////////////////
 // Constructor
 ////////////////////////////////////////////////////////////
@@ -47,6 +51,11 @@ ProcessThread::ProcessThread(const AudioFileModel &audioFile, const QString &out
        m_jobId(QUuid::createUuid()),
        m_aborted(false)
 {
+       if(m_mutex_genFileName)
+       {
+               m_mutex_genFileName = new QMutex;
+       }
+
        connect(m_encoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection);
 }
 
@@ -73,10 +82,13 @@ void ProcessThread::run()
 
        if(bSuccess)
        {
-               bSuccess = QFileInfo(outFileName).exists();
+               QFileInfo fileInfo(outFileName);
+               bSuccess = fileInfo.exists() && fileInfo.isFile() && (fileInfo.size() > 0);
        }
 
        emit processStateChanged(m_jobId, (bSuccess ? "Done." : (m_aborted ? "Aborted!" : "Failed!")), (bSuccess ? ProgressModel::JobComplete : ProgressModel::JobFailed));
+       emit processStateFinished(m_jobId, outFileName, bSuccess);
+
        qDebug("Process thread is done.");
 }
 
@@ -95,6 +107,8 @@ void ProcessThread::handleUpdate(int progress)
 
 QString ProcessThread::generateOutFileName(void)
 {
+       QMutexLocker lock(m_mutex_genFileName);
+       
        int n = 1;
 
        QString baseName = QFileInfo(m_audioFile.filePath()).completeBaseName();
@@ -107,6 +121,12 @@ QString ProcessThread::generateOutFileName(void)
                outFileName = QString("%1/%2 (%3).%4").arg(targetDir, baseName, QString::number(++n), m_encoder->extension());
        }
 
+       QFile placeholder(outFileName);
+       if(placeholder.open(QIODevice::WriteOnly))
+       {
+               placeholder.close();
+       }
+
        return outFileName;
 }
 
@@ -114,4 +134,4 @@ QString ProcessThread::generateOutFileName(void)
 // EVENTS
 ////////////////////////////////////////////////////////////
 
-/*NONE*/
\ No newline at end of file
+/*NONE*/
index 59d0193..a46001c 100644 (file)
@@ -27,6 +27,8 @@
 #include "Model_AudioFile.h"
 #include "Encoder_Abstract.h"
 
+class QMutex;
+
 class ProcessThread: public QThread
 {
        Q_OBJECT
@@ -44,6 +46,7 @@ private slots:
 signals:
        void processStateInitialized(const QUuid &jobId, const QString &jobName, const QString &jobInitialStatus, int jobInitialState);
        void processStateChanged(const QUuid &jobId, const QString &newStatus, int newState);
+       void processStateFinished(const QUuid &jobId, const QString &outFileName, bool success);
 
 private:
        QString generateOutFileName(void);
@@ -53,4 +56,6 @@ private:
        AbstractEncoder *m_encoder;
        const QString m_outputDirectory;
        volatile bool m_aborted;
+       
+       static QMutex *m_mutex_genFileName;
 };