Implemented logging and added a log file view.

This commit is contained in:
LoRd_MuldeR 2010-11-22 21:45:00 +01:00
parent efa535309d
commit c0ece99b69
19 changed files with 463 additions and 4 deletions

View File

@ -294,6 +294,10 @@
RelativePath=".\src\Dialog_About.cpp"
>
</File>
<File
RelativePath=".\src\Dialog_LogView.cpp"
>
</File>
<File
RelativePath=".\src\Dialog_MainWindow.cpp"
>
@ -422,6 +426,20 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\Dialog_LogView.h"
>
<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;"
Outputs="&quot;$(SolutionDir)tmp\MOC_$(SafeInputName).cpp&quot;"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\Dialog_MainWindow.h"
>
@ -970,6 +988,10 @@
RelativePath=".\tmp\MOC_Dialog_About.cpp"
>
</File>
<File
RelativePath=".\tmp\MOC_Dialog_LogView.cpp"
>
</File>
<File
RelativePath=".\tmp\MOC_Dialog_MainWindow.cpp"
>
@ -1164,6 +1186,20 @@
<Filter
Name="Dialogs"
>
<File
RelativePath=".\gui\LogViewDialog.ui"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="UIC &quot;$(SolutionDir)tmp\UIC_$(SafeInputName).h&quot;"
CommandLine="&quot;$(QTDIR)\bin\uic.exe&quot; -o &quot;$(SolutionDir)tmp\UIC_$(SafeInputName).h&quot; &quot;$(InputPath)&quot;"
Outputs="&quot;$(SolutionDir)tmp\UIC_$(SafeInputName).h&quot;"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\gui\MainWindow.ui"
>

203
gui/LogViewDialog.ui Normal file
View File

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LogViewDialog</class>
<widget class="QDialog" name="LogViewDialog">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>512</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>640</width>
<height>512</height>
</size>
</property>
<property name="windowTitle">
<string>Log View</string>
</property>
<property name="windowIcon">
<iconset resource="../res/Icons.qrc">
<normaloff>:/icons/application_xp_terminal.png</normaloff>:/icons/application_xp_terminal.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="4">
<widget class="QPlainTextEdit" name="textEdit">
<property name="palette">
<palette>
<active>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>255</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>31</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>255</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>31</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>120</red>
<green>120</green>
<blue>120</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>240</red>
<green>240</green>
<blue>240</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="font">
<font>
<family>Lucida Console</family>
</font>
</property>
<property name="plainText">
<string>C:\DOS
C:\DOS\RUN
RUN\DOS\RUN
</string>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="buttonDiscard">
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Discard</string>
</property>
<property name="icon">
<iconset resource="../res/Icons.qrc">
<normaloff>:/icons/cross.png</normaloff>:/icons/cross.png</iconset>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="buttonSave">
<property name="minimumSize">
<size>
<width>130</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Save to File...</string>
</property>
<property name="icon">
<iconset resource="../res/Icons.qrc">
<normaloff>:/icons/disk.png</normaloff>:/icons/disk.png</iconset>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="buttonCopy">
<property name="minimumSize">
<size>
<width>130</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Copy to Clipboard</string>
</property>
<property name="icon">
<iconset resource="../res/Icons.qrc">
<normaloff>:/icons/paste_plain.png</normaloff>:/icons/paste_plain.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../res/Icons.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonDiscard</sender>
<signal>clicked()</signal>
<receiver>LogViewDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>584</x>
<y>489</y>
</hint>
<hint type="destinationlabel">
<x>319</x>
<y>255</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -6,6 +6,7 @@
<file>icons/add.png</file>
<file>icons/accept.png</file>
<file>icons/application_view_list.png</file>
<file>icons/application_xp_terminal.png</file>
<file>icons/arrow_down.png</file>
<file>icons/arrow_up.png</file>
<file>icons/bin.png</file>
@ -26,6 +27,7 @@
<file>icons/cross.png</file>
<file>icons/date.png</file>
<file>icons/delete.png</file>
<file>icons/disk.png</file>
<file>icons/door_out.png</file>
<file>icons/drive_cd.png</file>
<file>icons/exclamation.png</file>
@ -42,6 +44,7 @@
<file>icons/package.png</file>
<file>icons/page_white_add.png</file>
<file>icons/page_white_cd.png</file>
<file>icons/paste_plain.png</file>
<file>icons/play.png</file>
<file>icons/resultset_next.png</file>
<file>icons/script_edit.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 62
#define VER_LAMEXP_BUILD 68
#define VER_LAMEXP_SUFFIX TechPreview
/*

84
src/Dialog_LogView.cpp Normal file
View File

@ -0,0 +1,84 @@
///////////////////////////////////////////////////////////////////////////////
// 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 "Dialog_LogView.h"
#include <QClipboard>
#include <QFileDialog>
LogViewDialog::LogViewDialog(QWidget *parent)
:
QDialog(parent)
{
//Init the dialog, from the .ui file
setupUi(this);
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint);
//setWindowFlags(windowFlags() & (~Qt::WindowMaximizeButtonHint));
//Clear
textEdit->clear();
//Enable buttons
connect(buttonCopy, SIGNAL(clicked()), this, SLOT(copyButtonClicked()));
connect(buttonSave, SIGNAL(clicked()), this, SLOT(saveButtonClicked()));
//Init flags
m_clipboardUsed = false;
}
LogViewDialog::~LogViewDialog(void)
{
if(m_clipboardUsed)
{
QApplication::clipboard()->clear();
}
}
int LogViewDialog::exec(const QStringList &logData)
{
textEdit->setPlainText(logData.join("\n"));
return QDialog::exec();
}
void LogViewDialog::copyButtonClicked(void)
{
QMimeData *mime = new QMimeData();
mime->setData("text/plain", textEdit->toPlainText().toUtf8().constData());
QApplication::clipboard()->setMimeData(mime);
m_clipboardUsed = true;
}
void LogViewDialog::saveButtonClicked(void)
{
QString fileName = QFileDialog::getSaveFileName(this, "Save Log File", QDir::homePath(), "Log Files (*.txt)");
if(!fileName.isEmpty())
{
QFile file(fileName);
if(file.open(QIODevice::WriteOnly))
{
QByteArray data = textEdit->toPlainText().toUtf8();
data.replace("\n", "\r\n");
file.write(data.constData(), data.size());
file.close();
}
}
}

44
src/Dialog_LogView.h Normal file
View File

@ -0,0 +1,44 @@
///////////////////////////////////////////////////////////////////////////////
// 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 "..\tmp\UIC_LogViewDialog.h"
#include <QDialog>
class LogViewDialog : public QDialog, private Ui::LogViewDialog
{
Q_OBJECT
public:
LogViewDialog(QWidget *parent = 0);
~LogViewDialog(void);
int exec(const QStringList &logData);
public slots:
void copyButtonClicked(void);
void saveButtonClicked(void);
private:
bool m_clipboardUsed;
};

View File

@ -27,6 +27,7 @@
#include "Model_Settings.h"
#include "Thread_Process.h"
#include "Encoder_MP3.h"
#include "Dialog_LogView.h"
#include <QApplication>
#include <QRect>
@ -87,6 +88,7 @@ ProcessingDialog::ProcessingDialog(FileListModel *fileListModel, AudioFileModel
view_log->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
connect(m_progressModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(progressModelChanged()));
connect(m_progressModel, SIGNAL(modelReset()), this, SLOT(progressModelChanged()));
connect(view_log, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(logViewDoubleClicked(QModelIndex)));
//Enque jobs
if(fileListModel)
@ -284,6 +286,17 @@ void ProcessingDialog::progressModelChanged(void)
view_log->scrollToBottom();
}
void ProcessingDialog::logViewDoubleClicked(const QModelIndex &index)
{
if(m_runningThreads == 0)
{
const QStringList &logFile = m_progressModel->getLogFile(index);
LogViewDialog *logView = new LogViewDialog(this);
logView->exec(logFile);
LAMEXP_DELETE(logView);
}
}
////////////////////////////////////////////////////////////
// Private Functions
////////////////////////////////////////////////////////////
@ -319,6 +332,7 @@ void ProcessingDialog::startNextJob(void)
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);
connect(thread, SIGNAL(processMessageLogged(QUuid,QString)), m_progressModel, SLOT(appendToLog(QUuid,QString)), Qt::QueuedConnection);
m_runningThreads++;
thread->start();
}

View File

@ -46,6 +46,7 @@ private slots:
void abortEncoding(void);
void processFinished(const QUuid &jobId, const QString &outFileName, bool success);
void progressModelChanged(void);
void logViewDoubleClicked(const QModelIndex &index);
protected:
void showEvent(QShowEvent *event);

View File

@ -21,6 +21,8 @@
#include "Encoder_Abstract.h"
#include <QStringList>
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
@ -37,3 +39,15 @@ AbstractEncoder::~AbstractEncoder(void)
//Setters
void AbstractEncoder::setBitrate(int bitrate) { m_configBitrate = max(0, bitrate); }
void AbstractEncoder::setRCMode(int mode) { m_configRCMode = max(0, mode); }
QString AbstractEncoder::commandline2string(const QString &program, const QStringList &arguments)
{
QString commandline = (program.contains(' ') ? QString("\"%1\"").arg(program) : program);
for(int i = 0; i < arguments.count(); i++)
{
commandline += (arguments.at(i).contains(' ') ? QString(" \"%1\"").arg(arguments.at(i)) : QString(" %1").arg(arguments.at(i)));
}
return commandline;
}

View File

@ -39,6 +39,8 @@ public:
void setBitrate(int bitrate);
void setRCMode(int mode);
static QString commandline2string(const QString &program, const QStringList &arguments);
protected:
int m_configBitrate;
int m_configRCMode;

View File

@ -86,6 +86,9 @@ bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputF
args << QDir::toNativeSeparators(sourceFile.filePath());
args << QDir::toNativeSeparators(outputFile);
emit messageLogged(commandline2string(m_binary, args));
emit messageLogged(QString());
process.start(m_binary, args);
if(!process.waitForStarted())
{
@ -125,7 +128,7 @@ bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputF
}
else if(!text.isEmpty())
{
qDebug("%s", text.toUtf8().constData());
emit messageLogged(text); //qDebug("%s", text.toUtf8().constData());
}
}
}

View File

@ -38,6 +38,7 @@ public:
signals:
void statusUpdated(int progress);
void messageLogged(const QString &line);
private:
const QString m_binary;

View File

@ -36,6 +36,7 @@
#include <QStringList>
#include <QSystemSemaphore>
#include <QMutex>
#include <QTextCodec>
//LameXP includes
#include "Resource.h"
@ -222,9 +223,9 @@ void lamexp_message_handler(QtMsgType type, const char *msg)
break;
case QtWarningMsg:
SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
//MessageBoxW(NULL, (wchar_t*) QString::fromUtf8(msg).utf16(), L"LameXP - CRITICAL ERROR", MB_ICONWARNING | MB_TOPMOST | MB_TASKMODAL);
fwprintf(stderr, L"%S\n", msg);
fflush(stderr);
//MessageBoxW(NULL, (wchar_t*) QString::fromUtf8(msg).utf16(), NULL, MB_TOPMOST | MB_ICONWARNING);
break;
default:
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);

View File

@ -51,6 +51,24 @@ int lamexp_main(int argc, char* argv[])
//Init console
lamexp_init_console(argc, argv);
//LPWSTR *szArglist;
//int nArgs;
//szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
//
//if(nArgs >= 2)
//{
// static HANDLE hConsole = NULL;
// hConsole = CreateFile(L"CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
// if(!SetConsoleCP(CP_UTF8))
// {
// wprintf(L"Failed to set CP !!!\n");
// }
// char buffer[4096];
// WideCharToMultiByte(CP_UTF8, 0, szArglist[1], -1, buffer, 4096, NULL, NULL);
// wprintf(L"%S\n", buffer);
// WriteConsoleA(hConsole, buffer, strlen(buffer), NULL, NULL);
//}
//Print version info
qDebug("LameXP - Audio Encoder Front-End");
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());

View File

@ -131,6 +131,7 @@ void ProgressModel::addJob(const QUuid &jobId, const QString &jobName, const QSt
m_jobName.insert(jobId, jobName);
m_jobStatus.insert(jobId, jobInitialStatus);
m_jobState.insert(jobId, jobInitialState);
m_jobLogFile.insert(jobId, QStringList());
endResetModel();
}
@ -145,5 +146,25 @@ void ProgressModel::updateJob(const QUuid &jobId, const QString &newStatus, int
if(!newStatus.isEmpty()) m_jobStatus.insert(jobId, newStatus);
if(newState >= 0) m_jobState.insert(jobId, newState);
emit dataChanged(index(row, 0), index(row, 1));
}
void ProgressModel::appendToLog(const QUuid &jobId, const QString &line)
{
if(m_jobList.contains(jobId))
{
m_jobLogFile[jobId].append(line);
}
}
const QStringList &ProgressModel::getLogFile(const QModelIndex &index)
{
if(index.row() < m_jobList.count())
{
QUuid id = m_jobList.at(index.row());
return m_jobLogFile[id];
}
return *(reinterpret_cast<QStringList*>(NULL));
}

View File

@ -52,15 +52,20 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
//Public functions
const QStringList &getLogFile(const QModelIndex &index);
public slots:
void addJob(const QUuid &jobId, const QString &jobName, const QString &jobInitialStatus = QString("Initializing..."), int jobInitialState = JobRunning);
void updateJob(const QUuid &jobId, const QString &newStatus, int newState);
void appendToLog(const QUuid &jobId, const QString &line);
private:
QList<QUuid> m_jobList;
QMap<QUuid, QString> m_jobName;
QMap<QUuid, QString> m_jobStatus;
QMap<QUuid, int> m_jobState;
QMap<QUuid, QStringList> m_jobLogFile;
const QIcon m_iconRunning;
const QIcon m_iconPaused;

View File

@ -30,6 +30,7 @@
#include <QProcess>
#include <QDate>
#include <QTime>
#include <QDebug>
#include <math.h>

View File

@ -57,6 +57,7 @@ ProcessThread::ProcessThread(const AudioFileModel &audioFile, const QString &out
}
connect(m_encoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection);
connect(m_encoder, SIGNAL(messageLogged(QString)), this, SLOT(handleMessage(QString)), Qt::DirectConnection);
}
ProcessThread::~ProcessThread(void)
@ -101,6 +102,11 @@ void ProcessThread::handleUpdate(int progress)
emit processStateChanged(m_jobId, QString("Encoding (%1%)").arg(QString::number(progress)), ProgressModel::JobRunning);
}
void ProcessThread::handleMessage(const QString &line)
{
emit processMessageLogged(m_jobId, line);
}
////////////////////////////////////////////////////////////
// PRIVAE FUNCTIONS
////////////////////////////////////////////////////////////

View File

@ -42,11 +42,13 @@ public:
private slots:
void handleUpdate(int progress);
void handleMessage(const QString &line);
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);
void processMessageLogged(const QUuid &jobId, const QString &line);
private:
QString generateOutFileName(void);