Implement processing thread and connect to processing dialog.

This commit is contained in:
LoRd_MuldeR 2010-11-18 00:32:46 +01:00
parent 2114a3dbf0
commit 3170f358fe
11 changed files with 416 additions and 28 deletions

View File

@ -374,6 +374,10 @@
RelativePath=".\src\Thread_MessageProducer.cpp"
>
</File>
<File
RelativePath=".\src\Thread_Process.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
@ -713,6 +717,36 @@
<File
RelativePath=".\src\Model_Progress.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
RelativePath=".\src\Model_Settings.h"
@ -862,6 +896,40 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\Thread_Process.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>
</Filter>
<Filter
Name="Generated Files"
@ -904,6 +972,10 @@
RelativePath=".\tmp\MOC_Model_MetaInfo.cpp"
>
</File>
<File
RelativePath=".\tmp\MOC_Model_Progress.cpp"
>
</File>
<File
RelativePath=".\tmp\MOC_Thread_FileAnalyzer.cpp"
>
@ -920,6 +992,10 @@
RelativePath=".\tmp\MOC_Thread_MessageProducer.cpp"
>
</File>
<File
RelativePath=".\tmp\MOC_Thread_Process.cpp"
>
</File>
<File
RelativePath=".\tmp\RCC_Icons.cpp"
>

View File

@ -16,6 +16,9 @@ if not "%ERRORLEVEL%"=="0" GOTO:EOF
echo ----------------------------------------------------------------
set "LAMEXP_ERROR=1"
msbuild.exe /property:Configuration=%2 /property:Platform=Win32 /target:Rebuild /verbosity:detailed %1
if not "%ERRORLEVEL%"=="0" GOTO:EOF
if not "%ERRORLEVEL%"=="0" (
msbuild.exe /property:Configuration=%2 /property:Platform=Win32 /target:Build /verbosity:detailed %1
if not "%ERRORLEVEL%"=="0" GOTO:EOF
)
echo ----------------------------------------------------------------
set "LAMEXP_ERROR=0"

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>663</width>
<height>458</height>
<height>454</height>
</rect>
</property>
<property name="windowTitle">
@ -30,13 +30,13 @@
<property name="minimumSize">
<size>
<width>0</width>
<height>72</height>
<height>64</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>72</height>
<height>64</height>
</size>
</property>
<property name="palette">
@ -138,14 +138,14 @@
<widget class="QLabel" name="label_headerIcon">
<property name="minimumSize">
<size>
<width>60</width>
<height>56</height>
<width>48</width>
<height>45</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>56</height>
<width>48</width>
<height>45</height>
</size>
</property>
<property name="text">
@ -283,6 +283,18 @@
<bold>false</bold>
</font>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderHighlightSections">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
@ -335,6 +347,9 @@
<bold>true</bold>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>(VERSION_TAG)</string>
</property>
@ -405,6 +420,14 @@
<include location="../res/Images.qrc"/>
<include location="../res/Icons.qrc"/>
<include location="../res/Images.qrc"/>
<include location="../res/Icons.qrc"/>
<include location="../res/Images.qrc"/>
<include location="../res/Icons.qrc"/>
<include location="../res/Images.qrc"/>
<include location="../res/Icons.qrc"/>
<include location="../res/Images.qrc"/>
<include location="../res/Icons.qrc"/>
<include location="../res/Images.qrc"/>
</resources>
<connections>
<connection>
@ -423,21 +446,5 @@
</hint>
</hints>
</connection>
<connection>
<sender>button_AbortProcess</sender>
<signal>clicked()</signal>
<receiver>ProcessingDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>453</x>
<y>422</y>
</hint>
<hint type="destinationlabel">
<x>331</x>
<y>228</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -36,6 +36,7 @@
<file>icons/folder_page.png</file>
<file>icons/house.png</file>
<file>icons/information.png</file>
<file>icons/media_play.png</file>
<file>icons/monitor.png</file>
<file>icons/music.png</file>
<file>icons/package.png</file>
@ -47,6 +48,7 @@
<file>icons/sound.png</file>
<file>icons/star.png</file>
<file>icons/table_edit.png</file>
<file>icons/tick.png</file>
<file>icons/timeline_marker.png</file>
<file>icons/transmit_blue.png</file>
<file>icons/user.png</file>

View 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 34
#define VER_LAMEXP_BUILD 38
#define VER_LAMEXP_SUFFIX TechPreview
/*

View File

@ -22,11 +22,23 @@
#include "Dialog_Processing.h"
#include "Global.h"
#include "Model_Progress.h"
#include "Thread_Process.h"
#include <QApplication>
#include <QRect>
#include <QDesktopWidget>
#include <QMovie>
#include <QMessageBox>
#include <QTimer>
#include <QCloseEvent>
#include <QDesktopServices>
#include <QUrl>
#include <Windows.h>
////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////
ProcessingDialog::ProcessingDialog(void)
{
@ -34,6 +46,7 @@ ProcessingDialog::ProcessingDialog(void)
setupUi(this);
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);
label_versionInfo->setText(QString().sprintf("v%d.%02d %s (Build %d)", lamexp_version_major(), lamexp_version_minor(), lamexp_version_release(), lamexp_version_build()));
label_versionInfo->installEventFilter(this);
//Center window in screen
QRect desktopRect = QApplication::desktop()->screenGeometry();
@ -41,14 +54,158 @@ ProcessingDialog::ProcessingDialog(void)
move((desktopRect.width() - thisRect.width()) / 2, (desktopRect.height() - thisRect.height()) / 2);
setMinimumSize(thisRect.width(), thisRect.height());
//Enable buttons
connect(button_AbortProcess, SIGNAL(clicked()), this, SLOT(abortEncoding()));
//Init progress indicator
m_progressIndicator = new QMovie(":/images/Working.gif");
label_headerWorking->setMovie(m_progressIndicator);
m_progressIndicator->start();
progressBar->setRange(0, 4);
progressBar->setValue(0);
//Init progress model
m_progressModel = new ProgressModel();
view_log->setModel(m_progressModel);
view_log->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
view_log->verticalHeader()->hide();
view_log->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
view_log->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
//Init member vars
for(int i = 0; i < 4; i++) m_thread[i] = NULL;
}
////////////////////////////////////////////////////////////
// Destructor
////////////////////////////////////////////////////////////
ProcessingDialog::~ProcessingDialog(void)
{
view_log->setModel(NULL);
if(m_progressIndicator) m_progressIndicator->stop();
LAMEXP_DELETE(m_progressIndicator);
LAMEXP_DELETE(m_progressModel);
}
////////////////////////////////////////////////////////////
// EVENTS
////////////////////////////////////////////////////////////
void ProcessingDialog::showEvent(QShowEvent *event)
{
setCloseButtonEnabled(false);
button_closeDialog->setEnabled(false);
button_AbortProcess->setEnabled(false);
QTimer::singleShot(1000, this, SLOT(initEncoding()));
}
void ProcessingDialog::closeEvent(QCloseEvent *event)
{
if(!button_closeDialog->isEnabled() || m_thread) event->ignore();
}
bool ProcessingDialog::eventFilter(QObject *obj, QEvent *event)
{
static QColor defaultColor = QColor();
if(obj == label_versionInfo)
{
if(event->type() == QEvent::Enter)
{
QPalette palette = label_versionInfo->palette();
defaultColor = palette.color(QPalette::Normal, QPalette::WindowText);
palette.setColor(QPalette::Normal, QPalette::WindowText, Qt::red);
label_versionInfo->setPalette(palette);
}
else if(event->type() == QEvent::Leave)
{
QPalette palette = label_versionInfo->palette();
palette.setColor(QPalette::Normal, QPalette::WindowText, defaultColor);
label_versionInfo->setPalette(palette);
}
else if(event->type() == QEvent::MouseButtonPress)
{
QUrl url("http://mulder.dummwiedeutsch.de/");
QDesktopServices::openUrl(url);
}
}
return false;
}
////////////////////////////////////////////////////////////
// SLOTS
////////////////////////////////////////////////////////////
void ProcessingDialog::initEncoding(void)
{
label_progress->setText("Encoding files, please wait...");
m_progressIndicator->start();
m_pendingJobs = 4;
for(int i = 0; i < 4; i++)
{
m_thread[i] = new ProcessThread();
connect(m_thread[i], SIGNAL(finished()), this, SLOT(doneEncoding()), Qt::QueuedConnection);
connect(m_thread[i], SIGNAL(processStateInitialized(QString,QString,QString,int)), m_progressModel, SLOT(addJob(QString,QString,QString,int)), Qt::QueuedConnection);
connect(m_thread[i], SIGNAL(processStateChanged(QString,QString,int)), m_progressModel, SLOT(updateJob(QString,QString,int)), Qt::QueuedConnection);
m_thread[i]->start();
}
button_closeDialog->setEnabled(false);
button_AbortProcess->setEnabled(true);
}
void ProcessingDialog::abortEncoding(void)
{
button_AbortProcess->setEnabled(false);
for(int i = 0; i < 4; i++)
{
if(m_thread[i])
{
m_thread[i]->abort();
}
}
}
void ProcessingDialog::doneEncoding(void)
{
progressBar->setValue(progressBar->value() + 1);
if(--m_pendingJobs > 0)
{
return;
}
label_progress->setText("Completed.");
m_progressIndicator->stop();
setCloseButtonEnabled(true);
button_closeDialog->setEnabled(true);
button_AbortProcess->setEnabled(false);
for(int i = 0; i < 4; i++)
{
if(m_thread[i])
{
m_thread[i]->terminate();
m_thread[i]->wait();
LAMEXP_DELETE(m_thread[i]);
}
}
progressBar->setValue(100);
}
////////////////////////////////////////////////////////////
// Private Functions
////////////////////////////////////////////////////////////
void ProcessingDialog::setCloseButtonEnabled(bool enabled)
{
HMENU hMenu = GetSystemMenu((HWND) winId(), FALSE);
EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_GRAYED));
}

View File

@ -24,6 +24,8 @@
#include "../tmp/UIC_ProcessingDialog.h"
class QMovie;
class ProgressModel;
class ProcessThread;
class ProcessingDialog : public QDialog, private Ui::ProcessingDialog
{
@ -33,6 +35,21 @@ public:
ProcessingDialog(void);
~ProcessingDialog(void);
private slots:
void initEncoding(void);
void doneEncoding(void);
void abortEncoding(void);
protected:
void showEvent(QShowEvent *event);
void closeEvent(QCloseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
private:
void setCloseButtonEnabled(bool enabled);
int m_pendingJobs;
QMovie *m_progressIndicator;
ProgressModel *m_progressModel;
ProcessThread *m_thread[4];
};

View File

@ -22,9 +22,9 @@
#include "Model_Progress.h"
ProgressModel::ProgressModel(void) :
m_iconRunning(":/icons/resultset_next.png"),
m_iconRunning(":/icons/media_play.png"),
m_iconPaused(":/icons/control_pause_blue.png"),
m_iconComplete(":/icons/accept.png"),
m_iconComplete(":/icons/tick.png"),
m_iconFailed(":/icons/exclamation.png")
{
}
@ -67,12 +67,16 @@ QVariant ProgressModel::data(const QModelIndex &index, int role) const
switch(m_jobState.value(m_jobList.at(index.row())))
{
case JobRunning:
return m_iconRunning;
break;
case JobPaused:
return m_iconPaused;
break;
case JobComplete:
return m_iconComplete;
break;
default:
return m_iconFailed;
break;
}
}

View File

@ -30,6 +30,8 @@
class ProgressModel : public QAbstractTableModel
{
Q_OBJECT
public:
ProgressModel(void);
~ProgressModel(void);

77
src/Thread_Process.cpp Normal file
View File

@ -0,0 +1,77 @@
///////////////////////////////////////////////////////////////////////////////
// LameXP - Audio Encoder Front-End
// Copyright (C) 2004-2010 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.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
#include "Thread_Process.h"
#include "Global.h"
#include "Model_Progress.h"
#include <QUuid.h>
#include <limits.h>
#include <time.h>
////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////
ProcessThread::ProcessThread(void)
: m_jobId(QUuid::createUuid().toString()), m_aborted(false)
{
}
ProcessThread::~ProcessThread(void)
{
}
void ProcessThread::run()
{
m_aborted = false;
qDebug("Process thread %s has started.", m_jobId.toLatin1().constData());
emit processStateInitialized(m_jobId, "Slime - Der Tod Ist Ein Meister Aus Deutschland.mp3", "Starting...", ProgressModel::JobRunning);
QUuid uuid = QUuid::createUuid();
qsrand(uuid.data1 * uuid.data2 * uuid.data3);
unsigned long delay = 250 + (qrand() % 500);
for(int i = 1; i <= 100; i++)
{
if(m_aborted)
{
emit processStateChanged(m_jobId, "Aborted.", ProgressModel::JobFailed);
return;
}
QThread::msleep(delay);
emit processStateChanged(m_jobId, QString("Encoding (%1%)").arg(i), ProgressModel::JobRunning);
qDebug("Process thread is alive.");
}
emit processStateChanged(m_jobId, "Done (100%)", ProgressModel::JobComplete);
qDebug("Process thread is about to die...");
}
////////////////////////////////////////////////////////////
// EVENTS
////////////////////////////////////////////////////////////
/*NONE*/

43
src/Thread_Process.h Normal file
View File

@ -0,0 +1,43 @@
///////////////////////////////////////////////////////////////////////////////
// LameXP - Audio Encoder Front-End
// Copyright (C) 2004-2010 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.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QThread>
class ProcessThread: public QThread
{
Q_OBJECT
public:
ProcessThread(void);
~ProcessThread(void);
void run();
void abort() { m_aborted = true; }
signals:
void processStateInitialized(const QString &jobId, const QString &jobName, const QString &jobInitialStatus, int jobInitialState);
void processStateChanged(const QString &jobId, const QString &newStatus, int newState);
private:
const QString m_jobId;
volatile bool m_aborted;
};