OSDN Git Service

Set creation/modified time of the encoded file the same value as the original file...
[lamexp/LameXP.git] / src / Thread_FileAnalyzer.cpp
index a10cbc8..e5f123f 100644 (file)
@@ -1,11 +1,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 // LameXP - Audio Encoder Front-End
-// Copyright (C) 2004-2013 LoRd_MuldeR <MuldeR2@GMX.de>
+// Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
+// (at your option) any later version, but always including the *additional*
+// restrictions defined in the "License.txt" file.
 //
 // This program is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 #include "Thread_FileAnalyzer.h"
 
+//Internal
 #include "Global.h"
 #include "LockedFile.h"
 #include "Model_AudioFile.h"
 #include "Thread_FileAnalyzer_Task.h"
 #include "PlaylistImporter.h"
 
+//MUtils
+#include <MUtils/Global.h>
+#include <MUtils/Exception.h>
+
+//Qt
 #include <QDir>
 #include <QFileInfo>
 #include <QProcess>
 #include <QTime>
 #include <QElapsedTimer>
 #include <QTimer>
+#include <QQueue>
+
+//Insert into QStringList *without* duplicates
+static inline void SAFE_APPEND_STRING(QStringList &list, const QString &str)
+{
+       if(!list.contains(str, Qt::CaseInsensitive))
+       {
+               list << str;
+       }
+}
 
 ////////////////////////////////////////////////////////////
 // Constructor
@@ -60,25 +77,24 @@ FileAnalyzer::FileAnalyzer(const QStringList &inputFiles)
        m_filesDummyCDDA = 0;
        m_filesCueSheet = 0;
 
+       moveToThread(this); /*makes sure queued slots are executed in the proper thread context*/
+
        m_timer = new QElapsedTimer;
 }
 
 FileAnalyzer::~FileAnalyzer(void)
 {
-       if(m_templateFile)
-       {
-               QString templatePath = m_templateFile->filePath();
-               LAMEXP_DELETE(m_templateFile);
-               if(QFile::exists(templatePath)) QFile::remove(templatePath);
-       }
-       
-       if(!m_pool->waitForDone(2500))
+       if(m_pool)
        {
-               qWarning("There are still running tasks in the thread pool!");
+               if(!m_pool->waitForDone(2500))
+               {
+                       qWarning("There are still running tasks in the thread pool!");
+               }
        }
 
-       LAMEXP_DELETE(m_pool);
-       LAMEXP_DELETE(m_timer);
+       MUTILS_DELETE(m_templateFile);
+       MUTILS_DELETE(m_pool);
+       MUTILS_DELETE(m_timer);
 }
 
 ////////////////////////////////////////////////////////////
@@ -146,10 +162,6 @@ void FileAnalyzer::run()
 
        m_timer->invalidate();
 
-       //Update progress
-       emit progressMaxChanged(m_inputFiles.count());
-       emit progressValChanged(0);
-
        //Create MediaInfo template file
        if(!m_templateFile)
        {
@@ -160,19 +172,30 @@ void FileAnalyzer::run()
                }
        }
 
-       //Handle playlist files
-       lamexp_natural_string_sort(m_inputFiles, true);
+       //Sort files
+       MUtils::natural_string_sort(m_inputFiles, true);
+
+       //Handle playlist files first!
        handlePlaylistFiles();
-       lamexp_natural_string_sort(m_inputFiles, true);
 
        const unsigned int nFiles = m_inputFiles.count();
+       if(nFiles < 1)
+       {
+               qWarning("File list is empty, nothing to do!");
+               return;
+       }
 
        //Update progress
        emit progressMaxChanged(nFiles);
+       emit progressValChanged(0);
 
        //Create thread pool
        if(!m_pool) m_pool = new QThreadPool();
-       m_pool->setMaxThreadCount(qBound(2, ((QThread::idealThreadCount() * 3) / 2), 12));
+       const int idealThreadCount = QThread::idealThreadCount();
+       if(idealThreadCount > 0)
+       {
+               m_pool->setMaxThreadCount(qBound(2, ((idealThreadCount * 3) / 2), 12));
+       }
 
        //Start first N threads
        QTimer::singleShot(0, this, SLOT(initializeTasks()));
@@ -221,7 +244,7 @@ bool FileAnalyzer::analyzeNextFile(void)
                const unsigned int taskId = m_tasksCounterNext++;
                const QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst());
 
-               if((!m_timer->isValid()) || (m_timer->elapsed() >= 250))
+               if((!m_timer->isValid()) || (m_timer->elapsed() >= 333))
                {
                        emit fileSelected(QFileInfo(currentFile).fileName());
                        m_timer->restart();
@@ -240,22 +263,51 @@ bool FileAnalyzer::analyzeNextFile(void)
 
 void FileAnalyzer::handlePlaylistFiles(void)
 {
-       QStringList importedFiles;
+       QQueue<QVariant> queue;
+       QStringList importedFromPlaylist;
+       
+       //Import playlist files into "hierarchical" list
        while(!m_inputFiles.isEmpty())
        {
                const QString currentFile = m_inputFiles.takeFirst();
-               if(!PlaylistImporter::importPlaylist(importedFiles, currentFile))
+               QStringList importedFiles;
+               if(PlaylistImporter::importPlaylist(importedFiles, currentFile))
+               {
+                       queue.enqueue(importedFiles);
+                       importedFromPlaylist << importedFiles;
+               }
+               else
                {
-                       importedFiles << currentFile;
+                       queue.enqueue(currentFile);
                }
        }
 
-       while(!importedFiles.isEmpty())
+       //Reduce temporary list
+       importedFromPlaylist.removeDuplicates();
+
+       //Now build the complete "flat" file list (files imported from playlist take precedence!)
+       while(!queue.isEmpty())
        {
-               const QString currentFile = importedFiles.takeFirst();
-               if(!m_inputFiles.contains(currentFile, Qt::CaseInsensitive))
+               const QVariant current = queue.dequeue();
+               if(current.type() == QVariant::String)
+               {
+                       const QString temp = current.toString();
+                       if(!importedFromPlaylist.contains(temp, Qt::CaseInsensitive))
+                       {
+                               SAFE_APPEND_STRING(m_inputFiles, temp);
+                       }
+               }
+               else if(current.type() == QVariant::StringList)
                {
-                       m_inputFiles << currentFile;
+                       const QStringList temp = current.toStringList();
+                       for(QStringList::ConstIterator iter = temp.constBegin(); iter != temp.constEnd(); iter++)
+                       {
+                               SAFE_APPEND_STRING(m_inputFiles, (*iter));
+                       }
+               }
+               else
+               {
+                       qWarning("Encountered an unexpected variant type!");
                }
        }
 }
@@ -268,7 +320,7 @@ bool FileAnalyzer::createTemplate(void)
                return true;
        }
        
-       QString templatePath = QString("%1/%2.txt").arg(lamexp_temp_folder2(), lamexp_rand_str());
+       QString templatePath = QString("%1/%2.txt").arg(MUtils::temp_folder(), MUtils::rand_str());
 
        QFile templateFile(templatePath);
        if(!templateFile.open(QIODevice::WriteOnly))
@@ -301,7 +353,12 @@ bool FileAnalyzer::createTemplate(void)
 
        try
        {
-               m_templateFile = new LockedFile(templatePath);
+               m_templateFile = new LockedFile(templatePath, true);
+       }
+       catch(const std::exception &error)
+       {
+               qWarning("Failed to lock template file:\n%s\n", error.what());
+               return false;
        }
        catch(...)
        {
@@ -355,7 +412,7 @@ void FileAnalyzer::taskFileAnalyzed(const unsigned int taskId, const int fileTyp
                m_filesRejected++;
                break;
        default:
-               throw "Unknown file type identifier!";
+               MUTILS_THROW("Unknown file type identifier!");
        }
 
        //Emit all pending files