Add ability to filter log messages by type.

This commit is contained in:
sledgehammer999 2016-01-24 21:38:45 +02:00
parent b0c324ace8
commit 73832a5ed8
10 changed files with 194 additions and 46 deletions

View file

@ -12,11 +12,13 @@ namespace Log
{
enum MsgType
{
NORMAL,
INFO,
WARNING,
CRITICAL //ERROR is defined by libtorrent and results in compiler error
ALL = -1,
NORMAL = 0x1,
INFO = 0x2,
WARNING = 0x4,
CRITICAL = 0x8 //ERROR is defined by libtorrent and results in compiler error
};
Q_DECLARE_FLAGS(MsgTypes, MsgType)
struct Msg
{
@ -36,6 +38,8 @@ namespace Log
};
}
Q_DECLARE_OPERATORS_FOR_FLAGS(Log::MsgTypes)
class Logger : public QObject
{
Q_OBJECT

View file

@ -871,6 +871,18 @@ void Preferences::setExecutionLogEnabled(bool b)
setValue("Preferences/ExecutionLog/enabled", b);
}
int Preferences::executionLogMessageTypes() const
{
// as default value we need all the bits set
// -1 is considered the portable way to achieve that
return value("MainWindow/ExecutionLog/Types", -1).toInt();
}
void Preferences::setExecutionLogMessageTypes(const int &value)
{
setValue("MainWindow/ExecutionLog/Types", value);
}
// Queueing system
bool Preferences::isQueueingSystemEnabled() const
{

View file

@ -276,6 +276,8 @@ public:
// Execution Log
bool isExecutionLogEnabled() const;
void setExecutionLogEnabled(bool b);
int executionLogMessageTypes() const;
void setExecutionLogMessageTypes(const int &value);
// Queueing system
bool isQueueingSystemEnabled() const;

View file

@ -35,18 +35,20 @@
#include <QPalette>
#include "executionlog.h"
#include "ui_executionlog.h"
#include "base/logger.h"
#include "base/preferences.h"
#include "guiiconprovider.h"
#include "loglistwidget.h"
ExecutionLog::ExecutionLog(QWidget *parent)
: QWidget(parent)
, ui(new Ui::ExecutionLog)
, m_msgList(new LogListWidget(MAX_LOG_MESSAGES))
, m_peerList(new LogListWidget(MAX_LOG_MESSAGES))
{
ui->setupUi(this);
m_msgList = new LogListWidget(MAX_LOG_MESSAGES,
Log::MsgTypes(Preferences::instance()->executionLogMessageTypes()));
ui->tabConsole->setTabIcon(0, GuiIconProvider::instance()->getIcon("view-calendar-journal"));
ui->tabConsole->setTabIcon(1, GuiIconProvider::instance()->getIcon("view-filter"));
ui->tabGeneral->layout()->addWidget(m_msgList);
@ -68,6 +70,11 @@ ExecutionLog::~ExecutionLog()
delete ui;
}
void ExecutionLog::showMsgTypes(const Log::MsgTypes &types)
{
m_msgList->showMsgTypes(types);
}
void ExecutionLog::addLogMessage(const Log::Msg &msg)
{
QString text;
@ -89,7 +96,7 @@ void ExecutionLog::addLogMessage(const Log::Msg &msg)
}
text = "<font color='grey'>" + time.toString(Qt::SystemLocaleShortDate) + "</font> - <font color='" + color.name() + "'>" + msg.message + "</font>";
m_msgList->appendLine(text);
m_msgList->appendLine(text, msg.type);
}
void ExecutionLog::addPeerMessage(const Log::Peer& peer)
@ -102,5 +109,5 @@ void ExecutionLog::addPeerMessage(const Log::Peer& peer)
else
text = "<font color='grey'>" + time.toString(Qt::SystemLocaleShortDate) + "</font> - " + tr("<font color='red'>%1</font> was banned", "x.y.z.w was banned").arg(peer.ip);
m_peerList->appendLine(text);
m_peerList->appendLine(text, Log::NORMAL);
}

View file

@ -32,27 +32,22 @@
#define EXECUTIONLOG_H
#include <QWidget>
#include "base/logger.h"
QT_BEGIN_NAMESPACE
namespace Ui {
class ExecutionLog;
}
QT_END_NAMESPACE
class Logger;
class LogListWidget;
namespace Log
{
struct Msg;
struct Peer;
}
class ExecutionLog: public QWidget
{
Q_OBJECT
public:
explicit ExecutionLog(QWidget *parent = 0);
void showMsgTypes(const Log::MsgTypes &types);
~ExecutionLog();
private slots:

View file

@ -37,9 +37,10 @@
#include "loglistwidget.h"
#include "guiiconprovider.h"
LogListWidget::LogListWidget(int max_lines, QWidget *parent) :
QListWidget(parent),
m_maxLines(max_lines)
LogListWidget::LogListWidget(int maxLines, const Log::MsgTypes &types, QWidget *parent)
: QListWidget(parent)
, m_maxLines(maxLines)
, m_types(types)
{
// Allow multiple selections
setSelectionMode(QAbstractItemView::ExtendedSelection);
@ -53,6 +54,18 @@ LogListWidget::LogListWidget(int max_lines, QWidget *parent) :
setContextMenuPolicy(Qt::ActionsContextMenu);
}
void LogListWidget::showMsgTypes(const Log::MsgTypes &types)
{
m_types = types;
for (int i = 0; i < count(); ++i) {
QListWidgetItem *tempItem = item(i);
if (!tempItem) continue;
Log::MsgType itemType = static_cast<Log::MsgType>(tempItem->data(Qt::UserRole).toInt());
setRowHidden(i, !(m_types & itemType));
}
}
void LogListWidget::keyPressEvent(QKeyEvent *event)
{
if (event->matches(QKeySequence::Copy))
@ -61,15 +74,18 @@ void LogListWidget::keyPressEvent(QKeyEvent *event)
selectAll();
}
void LogListWidget::appendLine(const QString &line)
void LogListWidget::appendLine(const QString &line, const Log::MsgType &type)
{
QListWidgetItem *item = new QListWidgetItem;
// We need to use QLabel here to support rich text
QLabel *lbl = new QLabel(line);
lbl->setContentsMargins(4, 2, 4, 2);
item->setSizeHint(lbl->sizeHint());
item->setData(Qt::UserRole, type);
insertItem(0, item);
setItemWidget(item, lbl);
setRowHidden(0, !(m_types & type));
const int nbLines = count();
// Limit log size
if (nbLines > m_maxLines)
@ -78,11 +94,10 @@ void LogListWidget::appendLine(const QString &line)
void LogListWidget::copySelection()
{
static QRegExp html_tag("<[^>]+>");
QList<QListWidgetItem*> items = selectedItems();
static QRegExp htmlTag("<[^>]+>");
QStringList strings;
foreach (QListWidgetItem* it, items)
strings << static_cast<QLabel*>(itemWidget(it))->text().replace(html_tag, "");
foreach (QListWidgetItem* it, selectedItems())
strings << static_cast<QLabel*>(itemWidget(it))->text().replace(htmlTag, "");
QApplication::clipboard()->setText(strings.join("\n"));
}

View file

@ -31,6 +31,7 @@
#define LOGLISTWIDGET_H
#include <QListWidget>
#include "base/logger.h"
QT_BEGIN_NAMESPACE
class QKeyEvent;
@ -41,10 +42,12 @@ class LogListWidget: public QListWidget
Q_OBJECT
public:
explicit LogListWidget(int max_lines = 100, QWidget *parent = 0);
// -1 is the portable way to have all the bits set
explicit LogListWidget(int maxLines, const Log::MsgTypes &types = Log::ALL, QWidget *parent = 0);
void showMsgTypes(const Log::MsgTypes &types);
public slots:
void appendLine(const QString &line);
void appendLine(const QString &line, const Log::MsgType &type);
protected slots:
void copySelection();
@ -54,7 +57,7 @@ protected:
private:
int m_maxLines;
Log::MsgTypes m_types;
};
#endif // LOGLISTWIDGET_H

View file

@ -273,9 +273,20 @@ MainWindow::MainWindow(QWidget *parent)
actionSpeed_in_title_bar->setChecked(pref->speedInTitleBar());
actionRSS_Reader->setChecked(pref->isRSSEnabled());
actionSearch_engine->setChecked(pref->isSearchEnabled());
actionExecution_Logs->setChecked(pref->isExecutionLogEnabled());
actionExecutionLogs->setChecked(pref->isExecutionLogEnabled());
Log::MsgTypes flags(pref->executionLogMessageTypes());
actionNormalMessages->setChecked(flags & Log::NORMAL);
actionInformationMessages->setChecked(flags & Log::INFO);
actionWarningMessages->setChecked(flags & Log::WARNING);
actionCriticalMessages->setChecked(flags & Log::CRITICAL);
displayRSSTab(actionRSS_Reader->isChecked());
on_actionExecution_Logs_triggered(actionExecution_Logs->isChecked());
on_actionExecutionLogs_triggered(actionExecutionLogs->isChecked());
on_actionNormalMessages_triggered(actionNormalMessages->isChecked());
on_actionInformationMessages_triggered(actionInformationMessages->isChecked());
on_actionWarningMessages_triggered(actionWarningMessages->isChecked());
on_actionCriticalMessages_triggered(actionCriticalMessages->isChecked());
if (actionSearch_engine->isChecked())
QTimer::singleShot(0, this, SLOT(on_actionSearch_engine_triggered()));
@ -1507,7 +1518,7 @@ void MainWindow::minimizeWindow()
setWindowState(windowState() ^ Qt::WindowMinimized);
}
void MainWindow::on_actionExecution_Logs_triggered(bool checked)
void MainWindow::on_actionExecutionLogs_triggered(bool checked)
{
if (checked) {
Q_ASSERT(!m_executionLog);
@ -1518,9 +1529,66 @@ void MainWindow::on_actionExecution_Logs_triggered(bool checked)
else if (m_executionLog) {
delete m_executionLog;
}
actionNormalMessages->setEnabled(checked);
actionInformationMessages->setEnabled(checked);
actionWarningMessages->setEnabled(checked);
actionCriticalMessages->setEnabled(checked);
Preferences::instance()->setExecutionLogEnabled(checked);
}
void MainWindow::on_actionNormalMessages_triggered(bool checked)
{
if (!m_executionLog)
return;
Preferences* const pref = Preferences::instance();
Log::MsgTypes flags(pref->executionLogMessageTypes());
checked ? (flags |= Log::NORMAL) : (flags &= ~Log::NORMAL);
m_executionLog->showMsgTypes(flags);
pref->setExecutionLogMessageTypes(flags);
}
void MainWindow::on_actionInformationMessages_triggered(bool checked)
{
if (!m_executionLog)
return;
Preferences* const pref = Preferences::instance();
Log::MsgTypes flags(pref->executionLogMessageTypes());
checked ? (flags |= Log::INFO) : (flags &= ~Log::INFO);
m_executionLog->showMsgTypes(flags);
pref->setExecutionLogMessageTypes(flags);
}
void MainWindow::on_actionWarningMessages_triggered(bool checked)
{
if (!m_executionLog)
return;
Preferences* const pref = Preferences::instance();
Log::MsgTypes flags(pref->executionLogMessageTypes());
checked ? (flags |= Log::WARNING) : (flags &= ~Log::WARNING);
m_executionLog->showMsgTypes(flags);
pref->setExecutionLogMessageTypes(flags);
}
void MainWindow::on_actionCriticalMessages_triggered(bool checked)
{
if (!m_executionLog)
return;
Preferences* const pref = Preferences::instance();
Log::MsgTypes flags(pref->executionLogMessageTypes());
checked ? (flags |= Log::CRITICAL) : (flags &= ~Log::CRITICAL);
m_executionLog->showMsgTypes(flags);
pref->setExecutionLogMessageTypes(flags);
}
void MainWindow::on_actionAutoExit_qBittorrent_toggled(bool enabled)
{
qDebug() << Q_FUNC_INFO << enabled;

View file

@ -214,7 +214,11 @@ private slots:
void on_actionTop_tool_bar_triggered();
void on_action_Import_Torrent_triggered();
void on_actionDonate_money_triggered();
void on_actionExecution_Logs_triggered(bool checked);
void on_actionExecutionLogs_triggered(bool checked);
void on_actionNormalMessages_triggered(bool checked);
void on_actionInformationMessages_triggered(bool checked);
void on_actionWarningMessages_triggered(bool checked);
void on_actionCriticalMessages_triggered(bool checked);
void on_actionAutoExit_qBittorrent_toggled(bool );
void on_actionAutoSuspend_system_toggled(bool );
void on_actionAutoHibernate_system_toggled(bool );

View file

@ -35,7 +35,7 @@
<x>0</x>
<y>0</y>
<width>914</width>
<height>22</height>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menu_Edit">
@ -95,12 +95,23 @@
<property name="title">
<string>&amp;View</string>
</property>
<widget class="QMenu" name="menuLog">
<property name="title">
<string>&amp;Log</string>
</property>
<addaction name="actionExecutionLogs"/>
<addaction name="separator"/>
<addaction name="actionNormalMessages"/>
<addaction name="actionInformationMessages"/>
<addaction name="actionWarningMessages"/>
<addaction name="actionCriticalMessages"/>
</widget>
<addaction name="actionTop_tool_bar"/>
<addaction name="actionSpeed_in_title_bar"/>
<addaction name="separator"/>
<addaction name="actionSearch_engine"/>
<addaction name="actionRSS_Reader"/>
<addaction name="actionExecution_Logs"/>
<addaction name="menuLog"/>
<addaction name="separator"/>
<addaction name="actionStatistics"/>
<addaction name="separator"/>
@ -340,17 +351,6 @@
<string>P&amp;ause All</string>
</property>
</action>
<action name="actionExecution_Logs">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Log</string>
</property>
<property name="toolTip">
<string>Execution Log</string>
</property>
</action>
<action name="actionAutoExit_qBittorrent">
<property name="checkable">
<bool>true</bool>
@ -414,9 +414,47 @@
<string>Check for Program Updates</string>
</property>
</action>
<action name="actionExecutionLogs">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show</string>
</property>
</action>
<action name="actionNormalMessages">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Normal Messages</string>
</property>
</action>
<action name="actionInformationMessages">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Information Messages</string>
</property>
</action>
<action name="actionWarningMessages">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Warning Messages</string>
</property>
</action>
<action name="actionCriticalMessages">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Critical Messages</string>
</property>
</action>
</widget>
<resources>
<include location="../icons.qrc"/>
</resources>
<resources/>
<connections/>
</ui>