OSDN Git Service

Fixed a potential memory leak.
[x264-launcher/x264-launcher.git] / src / model_jobList.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Simple x264 Launcher
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.
14 //
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.
18 //
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
21
22 #include "model_jobList.h"
23 #include "global.h"
24 #include "thread_encode.h"
25
26 #include <QIcon>
27
28 JobListModel::JobListModel(void)
29 {
30 }
31
32 JobListModel::~JobListModel(void)
33 {
34         while(!m_jobs.isEmpty())
35         {
36                 QUuid id = m_jobs.takeFirst();
37                 EncodeThread *thread = m_threads.value(id, NULL);
38                 LogFileModel *logFile = m_logFile.value(id, NULL);
39                 X264_DELETE(thread);
40                 X264_DELETE(logFile);
41         }
42 }
43
44 ///////////////////////////////////////////////////////////////////////////////
45 // Model interface
46 ///////////////////////////////////////////////////////////////////////////////
47
48 int JobListModel::columnCount(const QModelIndex &parent) const
49 {
50         return 4;
51 }
52
53 int JobListModel::rowCount(const QModelIndex &parent) const
54 {
55         return m_jobs.count();
56 }
57
58 QVariant JobListModel::headerData(int section, Qt::Orientation orientation, int role) const 
59 {
60         if((orientation == Qt::Horizontal) && (role == Qt::DisplayRole))
61         {
62                 switch(section)
63                 {
64                 case 0:
65                         return QVariant::fromValue<QString>(tr("Job"));
66                         break;
67                 case 1:
68                         return QVariant::fromValue<QString>(tr("Status"));
69                         break;
70                 case 2:
71                         return QVariant::fromValue<QString>(tr("Progress"));
72                         break;
73                 case 3:
74                         return QVariant::fromValue<QString>(tr("Details"));
75                         break;
76                 default:
77                         return QVariant();
78                         break;
79                 }
80         }
81
82         return QVariant();
83 }
84
85 QModelIndex JobListModel::index(int row, int column, const QModelIndex &parent) const
86 {
87         return createIndex(row, column, NULL);
88 }
89
90 QModelIndex JobListModel::parent(const QModelIndex &index) const
91 {
92         return QModelIndex();
93 }
94
95 QVariant JobListModel::data(const QModelIndex &index, int role) const
96 {
97         if(role == Qt::DisplayRole)
98         {
99                 if(index.row() >= 0 && index.row() < m_jobs.count())
100                 {
101                         switch(index.column())
102                         {
103                         case 0:
104                                 return m_jobs.at(index.row()).toString();
105                                 break;
106                         case 1:
107                                 switch(m_status.value(m_jobs.at(index.row())))
108                                 {
109                                 case EncodeThread::JobStatus_Enqueued:
110                                         return QVariant::fromValue<QString>(tr("Enqueued."));
111                                         break;
112                                 case EncodeThread::JobStatus_Starting:
113                                         return QVariant::fromValue<QString>(tr("Starting..."));
114                                         break;
115                                 case EncodeThread::JobStatus_Indexing:
116                                         return QVariant::fromValue<QString>(tr("Indexing..."));
117                                         break;
118                                 case EncodeThread::JobStatus_Running:
119                                         return QVariant::fromValue<QString>(tr("Running..."));
120                                         break;
121                                 case EncodeThread::JobStatus_Running_Pass1:
122                                         return QVariant::fromValue<QString>(tr("Running... (Pass 1)"));
123                                         break;
124                                 case EncodeThread::JobStatus_Running_Pass2:
125                                         return QVariant::fromValue<QString>(tr("Running... (Pass 2)"));
126                                         break;
127                                 case EncodeThread::JobStatus_Completed:
128                                         return QVariant::fromValue<QString>(tr("Completed."));
129                                         break;
130                                 case EncodeThread::JobStatus_Failed:
131                                         return QVariant::fromValue<QString>(tr("Failed!"));
132                                         break;
133                                 case EncodeThread::JobStatus_Aborting:
134                                         return QVariant::fromValue<QString>(tr("Aborting..."));
135                                         break;
136                                 case EncodeThread::JobStatus_Aborted:
137                                         return QVariant::fromValue<QString>(tr("Aborted!"));
138                                         break;
139                                 default:
140                                         return QVariant::fromValue<QString>(tr("(Unknown)"));
141                                         break;
142                                 }
143                                 break;
144                         case 2:
145                                 return QString().sprintf("%d%%", m_progress.value(m_jobs.at(index.row())));
146                                 break;
147                         case 3:
148                                 return m_details.value(m_jobs.at(index.row()));
149                                 break;
150                         default:
151                                 return QVariant();
152                                 break;
153                         }
154                 }
155         }
156         else if(role == Qt::DecorationRole)
157         {
158                 if(index.row() >= 0 && index.row() < m_jobs.count() && index.column() == 0)
159                 {
160                         switch(m_status.value(m_jobs.at(index.row())))
161                         {
162                         case EncodeThread::JobStatus_Enqueued:
163                                 return QIcon(":/buttons/clock_pause.png");
164                                 break;
165                         case EncodeThread::JobStatus_Starting:
166                                 return QIcon(":/buttons/lightning.png");
167                                 break;
168                         case EncodeThread::JobStatus_Indexing:
169                                 return QIcon(":/buttons/find.png");
170                                 break;
171                         case EncodeThread::JobStatus_Running:
172                         case EncodeThread::JobStatus_Running_Pass1:
173                         case EncodeThread::JobStatus_Running_Pass2:
174                                 return QIcon(":/buttons/play.png");
175                                 break;
176                         case EncodeThread::JobStatus_Completed:
177                                 return QIcon(":/buttons/accept.png");
178                                 break;
179                         case EncodeThread::JobStatus_Failed:
180                                 return QIcon(":/buttons/exclamation.png");
181                                 break;
182                         case EncodeThread::JobStatus_Aborting:
183                                 return QIcon(":/buttons/clock_stop.png");
184                                 break;
185                         case EncodeThread::JobStatus_Aborted:
186                                 return QIcon(":/buttons/error.png");
187                                 break;
188                         default:
189                                 return QVariant();
190                                 break;
191                         }
192                 }
193         }
194
195         return QVariant();
196 }
197
198 ///////////////////////////////////////////////////////////////////////////////
199 // Public interface
200 ///////////////////////////////////////////////////////////////////////////////
201
202 QModelIndex JobListModel::insertJob(EncodeThread *thread)
203 {
204         QUuid id = thread->getId();
205         LogFileModel *logFile = NULL;
206
207         if(m_jobs.contains(id))
208         {
209                 return QModelIndex();
210         }
211                 
212         beginInsertRows(QModelIndex(), m_jobs.count(), m_jobs.count());
213         m_jobs.append(id);
214         m_status.insert(id, EncodeThread::JobStatus_Enqueued);
215         m_progress.insert(id, 0);
216         m_threads.insert(id, thread);
217         m_logFile.insert(id, (logFile = new LogFileModel));
218         m_details.insert(id, tr("Not started yet."));
219         endInsertRows();
220
221         connect(thread, SIGNAL(statusChanged(QUuid, EncodeThread::JobStatus)), this, SLOT(updateStatus(QUuid, EncodeThread::JobStatus)), Qt::QueuedConnection);
222         connect(thread, SIGNAL(progressChanged(QUuid, unsigned int)), this, SLOT(updateProgress(QUuid, unsigned int)), Qt::QueuedConnection);
223         connect(thread, SIGNAL(messageLogged(QUuid, QString)), logFile, SLOT(addLogMessage(QUuid, QString)), Qt::QueuedConnection);
224         connect(thread, SIGNAL(detailsChanged(QUuid, QString)), this, SLOT(updateDetails(QUuid, QString)), Qt::QueuedConnection);
225         
226         return createIndex(m_jobs.count() - 1, 0, NULL);
227 }
228
229 bool JobListModel::startJob(const QModelIndex &index)
230 {
231         if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
232         {
233                 QUuid id = m_jobs.at(index.row());
234                 if(m_status.value(id) == EncodeThread::JobStatus_Enqueued)
235                 {
236                         updateStatus(id, EncodeThread::JobStatus_Starting);
237                         updateDetails(id, tr("Starting up, please wait..."));
238                         m_threads.value(id)->start();
239                         return true;
240                 }
241         }
242
243         return false;
244 }
245
246 bool JobListModel::abortJob(const QModelIndex &index)
247 {
248         if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
249         {
250                 QUuid id = m_jobs.at(index.row());
251                 if(m_status.value(id) == EncodeThread::JobStatus_Indexing || m_status.value(id) == EncodeThread::JobStatus_Running)
252                 {
253                         updateStatus(id, EncodeThread::JobStatus_Aborting);
254                         m_threads.value(id)->abortJob();
255                         return true;
256                 }
257         }
258
259         return false;
260 }
261
262 LogFileModel *JobListModel::getLogFile(const QModelIndex &index)
263 {
264         if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
265         {
266                 return m_logFile.value(m_jobs.at(index.row()));
267         }
268
269         return NULL;
270 }
271
272 EncodeThread::JobStatus JobListModel::getJobStatus(const QModelIndex &index)
273 {
274         if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
275         {
276                 return m_status.value(m_jobs.at(index.row()));
277         }
278
279         return static_cast<EncodeThread::JobStatus>(-1);
280 }
281
282 unsigned int JobListModel::getJobProgress(const QModelIndex &index)
283 {
284         if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
285         {
286                 return m_progress.value(m_jobs.at(index.row()));
287         }
288
289         return 0;
290 }
291
292 QModelIndex JobListModel::getJobIndexById(const QUuid &id)
293 {
294         if(m_jobs.contains(id))
295         {
296                 return createIndex(m_jobs.indexOf(id), 0);
297         }
298
299         return QModelIndex();
300 }
301
302 ///////////////////////////////////////////////////////////////////////////////
303 // Slots
304 ///////////////////////////////////////////////////////////////////////////////
305
306 void JobListModel::updateStatus(const QUuid &jobId, EncodeThread::JobStatus newStatus)
307 {
308         int index = -1;
309         
310         if((index = m_jobs.indexOf(jobId)) >= 0)
311         {
312                 m_status.insert(jobId, newStatus);
313                 emit dataChanged(createIndex(index, 0), createIndex(index, 1));
314         }
315 }
316
317 void JobListModel::updateProgress(const QUuid &jobId, unsigned int newProgress)
318 {
319         int index = -1;
320
321         if((index = m_jobs.indexOf(jobId)) >= 0)
322         {
323                 m_progress.insert(jobId, newProgress);
324                 emit dataChanged(createIndex(index, 2), createIndex(index, 2));
325         }
326 }
327
328 void JobListModel::updateDetails(const QUuid &jobId, const QString &details)
329 {
330         int index = -1;
331
332         if((index = m_jobs.indexOf(jobId)) >= 0)
333         {
334                 m_details.insert(jobId, details);
335                 emit dataChanged(createIndex(index, 3), createIndex(index, 3));
336         }
337 }