From c0ece99b6944bd9f0dd490f59a27b8c529811676 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Mon, 22 Nov 2010 21:45:00 +0100 Subject: [PATCH] Implemented logging and added a log file view. --- LameXP.vcproj | 36 +++++++ gui/LogViewDialog.ui | 203 ++++++++++++++++++++++++++++++++++++ res/Icons.qrc | 3 + src/Config.h | 2 +- src/Dialog_LogView.cpp | 84 +++++++++++++++ src/Dialog_LogView.h | 44 ++++++++ src/Dialog_Processing.cpp | 14 +++ src/Dialog_Processing.h | 1 + src/Encoder_Abstract.cpp | 14 +++ src/Encoder_Abstract.h | 2 + src/Encoder_MP3.cpp | 5 +- src/Encoder_MP3.h | 1 + src/Global.cpp | 5 +- src/Main.cpp | 18 ++++ src/Model_Progress.cpp | 21 ++++ src/Model_Progress.h | 5 + src/Thread_FileAnalyzer.cpp | 1 + src/Thread_Process.cpp | 6 ++ src/Thread_Process.h | 2 + 19 files changed, 463 insertions(+), 4 deletions(-) create mode 100644 gui/LogViewDialog.ui create mode 100644 src/Dialog_LogView.cpp create mode 100644 src/Dialog_LogView.h diff --git a/LameXP.vcproj b/LameXP.vcproj index 54117fe3..1f857873 100644 --- a/LameXP.vcproj +++ b/LameXP.vcproj @@ -294,6 +294,10 @@ RelativePath=".\src\Dialog_About.cpp" > + + @@ -422,6 +426,20 @@ /> + + + + + @@ -970,6 +988,10 @@ RelativePath=".\tmp\MOC_Dialog_About.cpp" > + + @@ -1164,6 +1186,20 @@ + + + + + diff --git a/gui/LogViewDialog.ui b/gui/LogViewDialog.ui new file mode 100644 index 00000000..ea0e5139 --- /dev/null +++ b/gui/LogViewDialog.ui @@ -0,0 +1,203 @@ + + + LogViewDialog + + + Qt::ApplicationModal + + + + 0 + 0 + 640 + 512 + + + + + 640 + 512 + + + + Log View + + + + :/icons/application_xp_terminal.png:/icons/application_xp_terminal.png + + + + + + + + + + + + + 170 + 255 + 0 + + + + + + + 0 + 31 + 0 + + + + + + + + + 170 + 255 + 0 + + + + + + + 0 + 31 + 0 + + + + + + + + + 120 + 120 + 120 + + + + + + + 240 + 240 + 240 + + + + + + + + + Lucida Console + + + + C:\DOS +C:\DOS\RUN +RUN\DOS\RUN + + + + Qt::NoTextInteraction + + + + + + + + 90 + 0 + + + + Discard + + + + :/icons/cross.png:/icons/cross.png + + + + + + + + 130 + 0 + + + + Save to File... + + + + :/icons/disk.png:/icons/disk.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 130 + 0 + + + + Copy to Clipboard + + + + :/icons/paste_plain.png:/icons/paste_plain.png + + + + + + + + + + + + + buttonDiscard + clicked() + LogViewDialog + reject() + + + 584 + 489 + + + 319 + 255 + + + + + diff --git a/res/Icons.qrc b/res/Icons.qrc index 610629ab..0f8a5553 100644 --- a/res/Icons.qrc +++ b/res/Icons.qrc @@ -6,6 +6,7 @@ icons/add.png icons/accept.png icons/application_view_list.png + icons/application_xp_terminal.png icons/arrow_down.png icons/arrow_up.png icons/bin.png @@ -26,6 +27,7 @@ icons/cross.png icons/date.png icons/delete.png + icons/disk.png icons/door_out.png icons/drive_cd.png icons/exclamation.png @@ -42,6 +44,7 @@ icons/package.png icons/page_white_add.png icons/page_white_cd.png + icons/paste_plain.png icons/play.png icons/resultset_next.png icons/script_edit.png diff --git a/src/Config.h b/src/Config.h index a86790e4..48528b0b 100644 --- a/src/Config.h +++ b/src/Config.h @@ -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 /* diff --git a/src/Dialog_LogView.cpp b/src/Dialog_LogView.cpp new file mode 100644 index 00000000..1deab260 --- /dev/null +++ b/src/Dialog_LogView.cpp @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2010 LoRd_MuldeR +// +// 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 +#include + +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(); + } + } +} diff --git a/src/Dialog_LogView.h b/src/Dialog_LogView.h new file mode 100644 index 00000000..e1e4cbe0 --- /dev/null +++ b/src/Dialog_LogView.h @@ -0,0 +1,44 @@ +/////////////////////////////////////////////////////////////////////////////// +// LameXP - Audio Encoder Front-End +// Copyright (C) 2004-2010 LoRd_MuldeR +// +// 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 + +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; +}; diff --git a/src/Dialog_Processing.cpp b/src/Dialog_Processing.cpp index 35571a07..de7952fe 100644 --- a/src/Dialog_Processing.cpp +++ b/src/Dialog_Processing.cpp @@ -27,6 +27,7 @@ #include "Model_Settings.h" #include "Thread_Process.h" #include "Encoder_MP3.h" +#include "Dialog_LogView.h" #include #include @@ -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(); } diff --git a/src/Dialog_Processing.h b/src/Dialog_Processing.h index 97aa9ab5..5fe602bd 100644 --- a/src/Dialog_Processing.h +++ b/src/Dialog_Processing.h @@ -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); diff --git a/src/Encoder_Abstract.cpp b/src/Encoder_Abstract.cpp index 43cc52ab..fdd44c6e 100644 --- a/src/Encoder_Abstract.cpp +++ b/src/Encoder_Abstract.cpp @@ -21,6 +21,8 @@ #include "Encoder_Abstract.h" +#include + #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; +} diff --git a/src/Encoder_Abstract.h b/src/Encoder_Abstract.h index 4719b0d1..dc8b2f2d 100644 --- a/src/Encoder_Abstract.h +++ b/src/Encoder_Abstract.h @@ -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; diff --git a/src/Encoder_MP3.cpp b/src/Encoder_MP3.cpp index 785d25a0..31181afb 100644 --- a/src/Encoder_MP3.cpp +++ b/src/Encoder_MP3.cpp @@ -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()); } } } diff --git a/src/Encoder_MP3.h b/src/Encoder_MP3.h index d64d9abb..677a4cf5 100644 --- a/src/Encoder_MP3.h +++ b/src/Encoder_MP3.h @@ -38,6 +38,7 @@ public: signals: void statusUpdated(int progress); + void messageLogged(const QString &line); private: const QString m_binary; diff --git a/src/Global.cpp b/src/Global.cpp index c9e8849e..28d2d5b3 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -36,6 +36,7 @@ #include #include #include +#include //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); @@ -420,7 +421,7 @@ bool lamexp_init_qt(int argc, char* argv[]) return false; } } - + //Done qt_initialized = true; return true; diff --git a/src/Main.cpp b/src/Main.cpp index 062fa9e0..c381d8f0 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -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()); diff --git a/src/Model_Progress.cpp b/src/Model_Progress.cpp index cc04b849..70166680 100644 --- a/src/Model_Progress.cpp +++ b/src/Model_Progress.cpp @@ -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(NULL)); +} diff --git a/src/Model_Progress.h b/src/Model_Progress.h index 8e0564c1..ea3c5840 100644 --- a/src/Model_Progress.h +++ b/src/Model_Progress.h @@ -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 m_jobList; QMap m_jobName; QMap m_jobStatus; QMap m_jobState; + QMap m_jobLogFile; const QIcon m_iconRunning; const QIcon m_iconPaused; diff --git a/src/Thread_FileAnalyzer.cpp b/src/Thread_FileAnalyzer.cpp index 0182af26..53aa4607 100644 --- a/src/Thread_FileAnalyzer.cpp +++ b/src/Thread_FileAnalyzer.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include diff --git a/src/Thread_Process.cpp b/src/Thread_Process.cpp index 59d57c7c..9c903979 100644 --- a/src/Thread_Process.cpp +++ b/src/Thread_Process.cpp @@ -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 //////////////////////////////////////////////////////////// diff --git a/src/Thread_Process.h b/src/Thread_Process.h index a46001cb..1c3c361a 100644 --- a/src/Thread_Process.h +++ b/src/Thread_Process.h @@ -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);