Rewrote FileListModel class to use a QHash map internally. This should speed-up the...
[LameXP.git] / src / Thread_FileAnalyzer.cpp
blob5e5b9e37a76ca7706897f364ae28660478dc3796
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2012 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
22 #include "Thread_FileAnalyzer.h"
24 #include "Global.h"
25 #include "LockedFile.h"
26 #include "Model_AudioFile.h"
27 #include "Thread_FileAnalyzer_Task.h"
29 #include <QDir>
30 #include <QFileInfo>
31 #include <QProcess>
32 #include <QDate>
33 #include <QTime>
34 #include <QDebug>
35 #include <QImage>
36 #include <QThreadPool>
38 ////////////////////////////////////////////////////////////
39 // Constructor
40 ////////////////////////////////////////////////////////////
42 FileAnalyzer::FileAnalyzer(const QStringList &inputFiles)
44 m_abortFlag(false),
45 m_inputFiles(inputFiles),
46 m_templateFile(NULL)
48 m_bSuccess = false;
49 m_bAborted = false;
52 FileAnalyzer::~FileAnalyzer(void)
54 if(m_templateFile)
56 QString templatePath = m_templateFile->filePath();
57 LAMEXP_DELETE(m_templateFile);
58 if(QFile::exists(templatePath)) QFile::remove(templatePath);
61 AnalyzeTask::reset();
64 ////////////////////////////////////////////////////////////
65 // Static data
66 ////////////////////////////////////////////////////////////
68 const char *FileAnalyzer::g_tags_gen[] =
70 "ID",
71 "Format",
72 "Format_Profile",
73 "Format_Version",
74 "Duration",
75 "Title", "Track",
76 "Track/Position",
77 "Artist", "Performer",
78 "Album",
79 "Genre",
80 "Released_Date", "Recorded_Date",
81 "Comment",
82 "Cover",
83 "Cover_Type",
84 "Cover_Mime",
85 "Cover_Data",
86 NULL
89 const char *FileAnalyzer::g_tags_aud[] =
91 "ID",
92 "Source",
93 "Format",
94 "Format_Profile",
95 "Format_Version",
96 "Channel(s)",
97 "SamplingRate",
98 "BitDepth",
99 "BitRate",
100 "BitRate_Mode",
101 NULL
104 ////////////////////////////////////////////////////////////
105 // Thread Main
106 ////////////////////////////////////////////////////////////
108 void FileAnalyzer::run()
110 m_bSuccess = false;
111 m_bAborted = false;
113 m_inputFiles.sort();
114 m_abortFlag = false;
116 if(!m_templateFile)
118 if(!createTemplate())
120 qWarning("Failed to create template file!");
121 return;
125 AnalyzeTask::reset();
126 QThreadPool *pool = new QThreadPool();
128 while(!(m_inputFiles.isEmpty() || m_bAborted))
130 while(!(m_inputFiles.isEmpty() || m_bAborted))
132 const QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst());
134 if(m_inputFiles.isEmpty())
136 pool->waitForDone();
139 AnalyzeTask *task = new AnalyzeTask(currentFile, m_templateFile->filePath(), &m_abortFlag);
140 connect(task, SIGNAL(fileSelected(QString)), this, SIGNAL(fileSelected(QString)), Qt::DirectConnection);
141 connect(task, SIGNAL(fileAnalyzed(AudioFileModel)), this, SIGNAL(fileAnalyzed(AudioFileModel)), Qt::DirectConnection);
143 while(!pool->tryStart(task))
145 QThread::msleep(125); //No more free threads, wait for active threads!
146 if(m_abortFlag) { LAMEXP_DELETE(task); break; }
149 if(m_abortFlag)
151 MessageBeep(MB_ICONERROR);
152 m_bAborted = true;
155 QThread::yieldCurrentThread();
158 if(!m_bAborted)
160 pool->waitForDone();
161 AnalyzeTask::getAdditionalFiles(m_inputFiles);
165 pool->waitForDone();
166 LAMEXP_DELETE(pool);
169 if(m_bAborted)
171 qWarning("Operation cancelled by user!");
172 return;
175 qDebug("All files added.\n");
176 m_bSuccess = true;
179 ////////////////////////////////////////////////////////////
180 // Privtae Functions
181 ////////////////////////////////////////////////////////////
183 bool FileAnalyzer::createTemplate(void)
185 if(m_templateFile)
187 qWarning("Template file already exists!");
188 return true;
191 QString templatePath = QString("%1/%2.txt").arg(lamexp_temp_folder2(), lamexp_rand_str());
193 QFile templateFile(templatePath);
194 if(!templateFile.open(QIODevice::WriteOnly))
196 return false;
199 templateFile.write("General;");
200 for(size_t i = 0; g_tags_gen[i]; i++)
202 templateFile.write(QString("Gen_%1=%%1%\\n").arg(g_tags_gen[i]).toLatin1().constData());
204 templateFile.write("\\n\r\n");
206 templateFile.write("Audio;");
207 for(size_t i = 0; g_tags_aud[i]; i++)
209 templateFile.write(QString("Aud_%1=%%1%\\n").arg(g_tags_aud[i]).toLatin1().constData());
211 templateFile.write("\\n\r\n");
213 bool success = (templateFile.error() == QFile::NoError);
214 templateFile.close();
216 if(!success)
218 QFile::remove(templatePath);
219 return false;
224 m_templateFile = new LockedFile(templatePath);
226 catch(...)
228 qWarning("Failed to lock template file!");
229 return false;
232 return true;
235 ////////////////////////////////////////////////////////////
236 // Public Functions
237 ////////////////////////////////////////////////////////////
239 unsigned int FileAnalyzer::filesAccepted(void)
241 return AnalyzeTask::filesAccepted();
244 unsigned int FileAnalyzer::filesRejected(void)
246 return AnalyzeTask::filesRejected();
249 unsigned int FileAnalyzer::filesDenied(void)
251 return AnalyzeTask::filesDenied();
254 unsigned int FileAnalyzer::filesDummyCDDA(void)
256 return AnalyzeTask::filesDummyCDDA();
259 unsigned int FileAnalyzer::filesCueSheet(void)
261 return AnalyzeTask::filesCueSheet();
264 ////////////////////////////////////////////////////////////
265 // EVENTS
266 ////////////////////////////////////////////////////////////
268 /*NONE*/