Mike Tzou
5 years ago
committed by
GitHub
14 changed files with 610 additions and 195 deletions
@ -0,0 +1,52 @@ |
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent. |
||||||
|
* Copyright (C) 2019 sledgehammer999 <hammered999@gmail.com> |
||||||
|
* |
||||||
|
* 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. |
||||||
|
* |
||||||
|
* In addition, as a special exception, the copyright holders give permission to |
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with |
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library), |
||||||
|
* and distribute the linked executables. You must obey the GNU General Public |
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you |
||||||
|
* modify file(s), you may extend this exception to your version of the file(s), |
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this |
||||||
|
* exception statement from your version. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "logfiltermodel.h" |
||||||
|
|
||||||
|
#include "logmodel.h" |
||||||
|
|
||||||
|
LogFilterModel::LogFilterModel(const Log::MsgTypes types, QObject *parent) |
||||||
|
: QSortFilterProxyModel(parent) |
||||||
|
, m_types(types) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
void LogFilterModel::setMessageTypes(const Log::MsgTypes types) |
||||||
|
{ |
||||||
|
m_types = types; |
||||||
|
invalidateFilter(); |
||||||
|
} |
||||||
|
|
||||||
|
bool LogFilterModel::filterAcceptsRow(const int sourceRow, const QModelIndex &sourceParent) const |
||||||
|
{ |
||||||
|
const QAbstractItemModel *const sourceModel = this->sourceModel(); |
||||||
|
const QModelIndex index = sourceModel->index(sourceRow, 0, sourceParent); |
||||||
|
const Log::MsgType type = static_cast<Log::MsgType>(sourceModel->data(index, BaseLogModel::TypeRole).toInt()); |
||||||
|
|
||||||
|
return m_types.testFlag(type); |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent. |
||||||
|
* Copyright (C) 2019 sledgehammer999 <hammered999@gmail.com> |
||||||
|
* |
||||||
|
* 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. |
||||||
|
* |
||||||
|
* In addition, as a special exception, the copyright holders give permission to |
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with |
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library), |
||||||
|
* and distribute the linked executables. You must obey the GNU General Public |
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you |
||||||
|
* modify file(s), you may extend this exception to your version of the file(s), |
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this |
||||||
|
* exception statement from your version. |
||||||
|
*/ |
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <QSortFilterProxyModel> |
||||||
|
|
||||||
|
#include "base/logger.h" |
||||||
|
|
||||||
|
class LogFilterModel : public QSortFilterProxyModel |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
Q_DISABLE_COPY(LogFilterModel) |
||||||
|
|
||||||
|
public: |
||||||
|
explicit LogFilterModel(Log::MsgTypes types = Log::ALL, QObject *parent = nullptr); |
||||||
|
void setMessageTypes(Log::MsgTypes types); |
||||||
|
|
||||||
|
private: |
||||||
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; |
||||||
|
|
||||||
|
Log::MsgTypes m_types; |
||||||
|
}; |
@ -0,0 +1,140 @@ |
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent. |
||||||
|
* Copyright (C) 2020 Prince Gupta <jagannatharjun11@gmail.com> |
||||||
|
* Copyright (C) 2019 sledgehammer999 <hammered999@gmail.com> |
||||||
|
* |
||||||
|
* 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. |
||||||
|
* |
||||||
|
* In addition, as a special exception, the copyright holders give permission to |
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with |
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library), |
||||||
|
* and distribute the linked executables. You must obey the GNU General Public |
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you |
||||||
|
* modify file(s), you may extend this exception to your version of the file(s), |
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this |
||||||
|
* exception statement from your version. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "loglistview.h" |
||||||
|
|
||||||
|
#include <QApplication> |
||||||
|
#include <QClipboard> |
||||||
|
#include <QFontMetrics> |
||||||
|
#include <QKeyEvent> |
||||||
|
#include <QPainter> |
||||||
|
#include <QStyle> |
||||||
|
#include <QStyledItemDelegate> |
||||||
|
|
||||||
|
#include "logmodel.h" |
||||||
|
#include "uithememanager.h" |
||||||
|
|
||||||
|
namespace |
||||||
|
{ |
||||||
|
const QString SEPARATOR = QStringLiteral(" - "); |
||||||
|
|
||||||
|
int horizontalAdvance(const QFontMetrics &fontMetrics, const QString &text) |
||||||
|
{ |
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) |
||||||
|
return fontMetrics.horizontalAdvance(text); |
||||||
|
#else |
||||||
|
return fontMetrics.width(text); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
QString logText(const QModelIndex &index) |
||||||
|
{ |
||||||
|
return QString::fromLatin1("%1%2%3").arg(index.data(BaseLogModel::TimeRole).toString(), SEPARATOR |
||||||
|
, index.data(BaseLogModel::MessageRole).toString()); |
||||||
|
} |
||||||
|
|
||||||
|
class LogItemDelegate : public QStyledItemDelegate |
||||||
|
{ |
||||||
|
public: |
||||||
|
using QStyledItemDelegate::QStyledItemDelegate; |
||||||
|
|
||||||
|
private: |
||||||
|
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override |
||||||
|
{ |
||||||
|
painter->save(); |
||||||
|
QStyledItemDelegate::paint(painter, option, index); // paints background, focus rect and selection rect
|
||||||
|
|
||||||
|
const QStyle *style = option.widget ? option.widget->style() : QApplication::style();; |
||||||
|
const QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &option, option.widget) |
||||||
|
.adjusted(1, 0, 0, 0); // shift 1 to avoid text being too close to focus rect
|
||||||
|
|
||||||
|
QFont font = option.font; |
||||||
|
if (option.font.pointSize() > 0) |
||||||
|
font.setPointSize(option.font.pointSize()); // somehow this needs to be set directly otherwise painter will use default font
|
||||||
|
painter->setFont(font); |
||||||
|
|
||||||
|
const QPen originalPen = painter->pen(); |
||||||
|
QPen coloredPen = originalPen; |
||||||
|
coloredPen.setColor(Qt::darkGray); |
||||||
|
painter->setPen(coloredPen); |
||||||
|
const QString time = index.data(BaseLogModel::TimeRole).toString(); |
||||||
|
style->drawItemText(painter, textRect, option.displayAlignment, option.palette, (option.state & QStyle::State_Enabled), time); |
||||||
|
|
||||||
|
painter->setPen(originalPen); |
||||||
|
const QFontMetrics fontMetrics = painter->fontMetrics(); // option.fontMetrics adds extra padding to QFontMetrics::width
|
||||||
|
const int separatorCoordinateX = horizontalAdvance(fontMetrics, time); |
||||||
|
style->drawItemText(painter, textRect.adjusted(separatorCoordinateX, 0, 0, 0), option.displayAlignment, option.palette |
||||||
|
, (option.state & QStyle::State_Enabled), SEPARATOR); |
||||||
|
|
||||||
|
coloredPen.setColor(index.data(BaseLogModel::ForegroundRole).value<QColor>()); |
||||||
|
painter->setPen(coloredPen); |
||||||
|
const int messageCoordinateX = separatorCoordinateX + horizontalAdvance(fontMetrics, SEPARATOR); |
||||||
|
style->drawItemText(painter, textRect.adjusted(messageCoordinateX, 0, 0, 0), option.displayAlignment, option.palette |
||||||
|
, (option.state & QStyle::State_Enabled), index.data(BaseLogModel::MessageRole).toString()); |
||||||
|
painter->restore(); |
||||||
|
} |
||||||
|
|
||||||
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override |
||||||
|
{ |
||||||
|
const QSize minimumFontPadding(4, 4); |
||||||
|
const QSize fontSize = option.fontMetrics.size(0, logText(index)) + minimumFontPadding; |
||||||
|
const QSize defaultSize = QStyledItemDelegate::sizeHint(option, index); |
||||||
|
const QSize margins = (defaultSize - fontSize).expandedTo({0, 0}); |
||||||
|
return fontSize + margins; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
LogListView::LogListView(QWidget *parent) |
||||||
|
: QListView(parent) |
||||||
|
{ |
||||||
|
setSelectionMode(QAbstractItemView::ExtendedSelection); |
||||||
|
setItemDelegate(new LogItemDelegate(this)); |
||||||
|
|
||||||
|
#if defined(Q_OS_MAC) |
||||||
|
setAttribute(Qt::WA_MacShowFocusRect, false); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
void LogListView::keyPressEvent(QKeyEvent *event) |
||||||
|
{ |
||||||
|
if (event->matches(QKeySequence::Copy)) |
||||||
|
copySelection(); |
||||||
|
else |
||||||
|
QListView::keyPressEvent(event); |
||||||
|
} |
||||||
|
|
||||||
|
void LogListView::copySelection() const |
||||||
|
{ |
||||||
|
QStringList list; |
||||||
|
const QModelIndexList selectedIndexes = selectionModel()->selectedRows(); |
||||||
|
for (const QModelIndex &index : selectedIndexes) |
||||||
|
list.append(logText(index)); |
||||||
|
QApplication::clipboard()->setText(list.join('\n')); |
||||||
|
} |
@ -0,0 +1,188 @@ |
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent. |
||||||
|
* Copyright (C) 2020 Prince Gupta <jagannatharjun11@gmail.com> |
||||||
|
* Copyright (C) 2019 sledgehammer999 <hammered999@gmail.com> |
||||||
|
* |
||||||
|
* 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. |
||||||
|
* |
||||||
|
* In addition, as a special exception, the copyright holders give permission to |
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with |
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library), |
||||||
|
* and distribute the linked executables. You must obey the GNU General Public |
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you |
||||||
|
* modify file(s), you may extend this exception to your version of the file(s), |
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this |
||||||
|
* exception statement from your version. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "logmodel.h" |
||||||
|
|
||||||
|
#include <QApplication> |
||||||
|
#include <QDateTime> |
||||||
|
#include <QColor> |
||||||
|
#include <QPalette> |
||||||
|
|
||||||
|
#include "base/global.h" |
||||||
|
|
||||||
|
namespace |
||||||
|
{ |
||||||
|
const int MAX_VISIBLE_MESSAGES = 20000; |
||||||
|
} |
||||||
|
|
||||||
|
BaseLogModel::Message::Message(const QString &time, const QString &message, const QColor &foreground, const Log::MsgType type) |
||||||
|
: m_time(time) |
||||||
|
, m_message(message) |
||||||
|
, m_foreground(foreground) |
||||||
|
, m_type(type) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
QVariant BaseLogModel::Message::time() const |
||||||
|
{ |
||||||
|
return m_time; |
||||||
|
} |
||||||
|
|
||||||
|
QVariant BaseLogModel::Message::message() const |
||||||
|
{ |
||||||
|
return m_message; |
||||||
|
} |
||||||
|
|
||||||
|
QVariant BaseLogModel::Message::foreground() const |
||||||
|
{ |
||||||
|
return m_foreground; |
||||||
|
} |
||||||
|
|
||||||
|
QVariant BaseLogModel::Message::type() const |
||||||
|
{ |
||||||
|
return m_type; |
||||||
|
} |
||||||
|
|
||||||
|
BaseLogModel::BaseLogModel(QObject *parent) |
||||||
|
: QAbstractListModel(parent) |
||||||
|
, m_messages(MAX_VISIBLE_MESSAGES) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
int BaseLogModel::rowCount(const QModelIndex &) const |
||||||
|
{ |
||||||
|
return m_messages.size(); |
||||||
|
} |
||||||
|
|
||||||
|
int BaseLogModel::columnCount(const QModelIndex &) const |
||||||
|
{ |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
QVariant BaseLogModel::data(const QModelIndex &index, const int role) const |
||||||
|
{ |
||||||
|
if (!index.isValid()) |
||||||
|
return {}; |
||||||
|
|
||||||
|
const int messageIndex = index.row(); |
||||||
|
if ((messageIndex < 0) || (messageIndex >= static_cast<int>(m_messages.size()))) |
||||||
|
return {}; |
||||||
|
|
||||||
|
const Message &message = m_messages[messageIndex]; |
||||||
|
switch (role) { |
||||||
|
case TimeRole: |
||||||
|
return message.time(); |
||||||
|
case MessageRole: |
||||||
|
return message.message(); |
||||||
|
case ForegroundRole: |
||||||
|
return message.foreground(); |
||||||
|
case TypeRole: |
||||||
|
return message.type(); |
||||||
|
default: |
||||||
|
return {}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void BaseLogModel::addNewMessage(const BaseLogModel::Message &message) |
||||||
|
{ |
||||||
|
// if row is inserted on filled up buffer, the size will not change
|
||||||
|
// but because of calling of beginInsertRows function we'll have ghost rows.
|
||||||
|
if (m_messages.size() == MAX_VISIBLE_MESSAGES) { |
||||||
|
const int lastMessage = m_messages.size() - 1; |
||||||
|
beginRemoveRows(QModelIndex(), lastMessage, lastMessage); |
||||||
|
m_messages.pop_back(); |
||||||
|
endRemoveRows(); |
||||||
|
} |
||||||
|
|
||||||
|
beginInsertRows(QModelIndex(), 0, 0); |
||||||
|
m_messages.push_front(message); |
||||||
|
endInsertRows(); |
||||||
|
} |
||||||
|
|
||||||
|
void BaseLogModel::reset() |
||||||
|
{ |
||||||
|
beginResetModel(); |
||||||
|
m_messages.clear(); |
||||||
|
endResetModel(); |
||||||
|
} |
||||||
|
|
||||||
|
LogMessageModel::LogMessageModel(QObject *parent) |
||||||
|
: BaseLogModel(parent) |
||||||
|
{ |
||||||
|
for (const Log::Msg &msg : asConst(Logger::instance()->getMessages())) |
||||||
|
handleNewMessage(msg); |
||||||
|
connect(Logger::instance(), &Logger::newLogMessage, this, &LogMessageModel::handleNewMessage); |
||||||
|
} |
||||||
|
|
||||||
|
void LogMessageModel::handleNewMessage(const Log::Msg &message) |
||||||
|
{ |
||||||
|
const QString time = QDateTime::fromMSecsSinceEpoch(message.timestamp).toString(Qt::SystemLocaleShortDate); |
||||||
|
const QString messageText = message.message; |
||||||
|
|
||||||
|
QColor foreground; |
||||||
|
switch (message.type) { |
||||||
|
// The RGB QColor constructor is used for performance
|
||||||
|
case Log::NORMAL: |
||||||
|
foreground = QApplication::palette().color(QPalette::WindowText); |
||||||
|
break; |
||||||
|
case Log::INFO: |
||||||
|
foreground = QColor(0, 0, 255); // blue
|
||||||
|
break; |
||||||
|
case Log::WARNING: |
||||||
|
foreground = QColor(255, 165, 0); // orange
|
||||||
|
break; |
||||||
|
case Log::CRITICAL: |
||||||
|
foreground = QColor(255, 0, 0); // red
|
||||||
|
break; |
||||||
|
default: |
||||||
|
Q_ASSERT(false); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
addNewMessage({time, messageText, foreground, message.type}); |
||||||
|
} |
||||||
|
|
||||||
|
LogPeerModel::LogPeerModel(QObject *parent) |
||||||
|
: BaseLogModel(parent) |
||||||
|
{ |
||||||
|
for (const Log::Peer &peer : asConst(Logger::instance()->getPeers())) |
||||||
|
handleNewMessage(peer); |
||||||
|
connect(Logger::instance(), &Logger::newLogPeer, this, &LogPeerModel::handleNewMessage); |
||||||
|
} |
||||||
|
|
||||||
|
void LogPeerModel::handleNewMessage(const Log::Peer &peer) |
||||||
|
{ |
||||||
|
const QString time = QDateTime::fromMSecsSinceEpoch(peer.timestamp).toString(Qt::SystemLocaleShortDate); |
||||||
|
const QString message = peer.blocked |
||||||
|
? tr("%1 was blocked due to %2", "0.0.0.0 was blocked due to reason").arg(peer.ip, peer.reason) |
||||||
|
: tr("%1 was banned", "0.0.0.0 was banned").arg(peer.ip); |
||||||
|
const QColor foreground = Qt::red; |
||||||
|
|
||||||
|
addNewMessage({time, message, foreground, Log::NORMAL}); |
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt and libtorrent. |
||||||
|
* Copyright (C) 2020 Prince Gupta <jagannatharjun11@gmail.com> |
||||||
|
* Copyright (C) 2019 sledgehammer999 <hammered999@gmail.com> |
||||||
|
* |
||||||
|
* 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. |
||||||
|
* |
||||||
|
* In addition, as a special exception, the copyright holders give permission to |
||||||
|
* link this program with the OpenSSL project's "OpenSSL" library (or with |
||||||
|
* modified versions of it that use the same license as the "OpenSSL" library), |
||||||
|
* and distribute the linked executables. You must obey the GNU General Public |
||||||
|
* License in all respects for all of the code used other than "OpenSSL". If you |
||||||
|
* modify file(s), you may extend this exception to your version of the file(s), |
||||||
|
* but you are not obligated to do so. If you do not wish to do so, delete this |
||||||
|
* exception statement from your version. |
||||||
|
*/ |
||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <boost/circular_buffer.hpp> |
||||||
|
|
||||||
|
#include <QAbstractListModel> |
||||||
|
|
||||||
|
#include "base/logger.h" |
||||||
|
|
||||||
|
class BaseLogModel : public QAbstractListModel |
||||||
|
{ |
||||||
|
Q_DISABLE_COPY(BaseLogModel) |
||||||
|
|
||||||
|
public: |
||||||
|
enum MessageTypeRole |
||||||
|
{ |
||||||
|
TimeRole = Qt::UserRole, |
||||||
|
MessageRole, |
||||||
|
ForegroundRole, |
||||||
|
TypeRole |
||||||
|
}; |
||||||
|
|
||||||
|
explicit BaseLogModel(QObject *parent = nullptr); |
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = {}) const override; |
||||||
|
int columnCount(const QModelIndex &parent = {}) const override; |
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; |
||||||
|
void reset(); |
||||||
|
|
||||||
|
protected: |
||||||
|
class Message |
||||||
|
{ |
||||||
|
public: |
||||||
|
Message(const QString &time, const QString &message, const QColor &foreground, Log::MsgType type); |
||||||
|
|
||||||
|
QVariant time() const; |
||||||
|
QVariant message() const; |
||||||
|
QVariant foreground() const; |
||||||
|
QVariant type() const; |
||||||
|
|
||||||
|
private: |
||||||
|
QVariant m_time; |
||||||
|
QVariant m_message; |
||||||
|
QVariant m_foreground; |
||||||
|
QVariant m_type; |
||||||
|
}; |
||||||
|
|
||||||
|
void addNewMessage(const Message &message); |
||||||
|
|
||||||
|
private: |
||||||
|
boost::circular_buffer_space_optimized<Message> m_messages; |
||||||
|
}; |
||||||
|
|
||||||
|
class LogMessageModel : public BaseLogModel |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
Q_DISABLE_COPY(LogMessageModel) |
||||||
|
|
||||||
|
public: |
||||||
|
explicit LogMessageModel(QObject *parent = nullptr); |
||||||
|
|
||||||
|
private slots: |
||||||
|
void handleNewMessage(const Log::Msg &message); |
||||||
|
}; |
||||||
|
|
||||||
|
class LogPeerModel : public BaseLogModel |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
Q_DISABLE_COPY(LogPeerModel) |
||||||
|
|
||||||
|
public: |
||||||
|
explicit LogPeerModel(QObject *parent = nullptr); |
||||||
|
|
||||||
|
private slots: |
||||||
|
void handleNewMessage(const Log::Peer &peer); |
||||||
|
}; |
@ -1,108 +0,0 @@ |
|||||||
/*
|
|
||||||
* Bittorrent Client using Qt and libtorrent. |
|
||||||
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org> |
|
||||||
* |
|
||||||
* 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. |
|
||||||
* |
|
||||||
* In addition, as a special exception, the copyright holders give permission to |
|
||||||
* link this program with the OpenSSL project's "OpenSSL" library (or with |
|
||||||
* modified versions of it that use the same license as the "OpenSSL" library), |
|
||||||
* and distribute the linked executables. You must obey the GNU General Public |
|
||||||
* License in all respects for all of the code used other than "OpenSSL". If you |
|
||||||
* modify file(s), you may extend this exception to your version of the file(s), |
|
||||||
* but you are not obligated to do so. If you do not wish to do so, delete this |
|
||||||
* exception statement from your version. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include "loglistwidget.h" |
|
||||||
|
|
||||||
#include <QAction> |
|
||||||
#include <QApplication> |
|
||||||
#include <QClipboard> |
|
||||||
#include <QKeyEvent> |
|
||||||
#include <QLabel> |
|
||||||
#include <QListWidgetItem> |
|
||||||
#include <QRegularExpression> |
|
||||||
|
|
||||||
#include "base/global.h" |
|
||||||
#include "uithememanager.h" |
|
||||||
|
|
||||||
LogListWidget::LogListWidget(const int maxLines, const Log::MsgTypes &types, QWidget *parent) |
|
||||||
: QListWidget(parent) |
|
||||||
, m_maxLines(maxLines) |
|
||||||
, m_types(types) |
|
||||||
{ |
|
||||||
// Allow multiple selections
|
|
||||||
setSelectionMode(QAbstractItemView::ExtendedSelection); |
|
||||||
// Context menu
|
|
||||||
auto *copyAct = new QAction(UIThemeManager::instance()->getIcon("edit-copy"), tr("Copy"), this); |
|
||||||
auto *clearAct = new QAction(UIThemeManager::instance()->getIcon("edit-clear"), tr("Clear"), this); |
|
||||||
connect(copyAct, &QAction::triggered, this, &LogListWidget::copySelection); |
|
||||||
connect(clearAct, &QAction::triggered, this, &LogListWidget::clear); |
|
||||||
addAction(copyAct); |
|
||||||
addAction(clearAct); |
|
||||||
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)) |
|
||||||
copySelection(); |
|
||||||
else |
|
||||||
QListWidget::keyPressEvent(event); |
|
||||||
} |
|
||||||
|
|
||||||
void LogListWidget::appendLine(const QString &line, const Log::MsgType &type) |
|
||||||
{ |
|
||||||
// We need to use QLabel here to support rich text
|
|
||||||
auto *lbl = new QLabel(line); |
|
||||||
lbl->setTextFormat(Qt::RichText); |
|
||||||
lbl->setContentsMargins(4, 2, 4, 2); |
|
||||||
|
|
||||||
auto *item = new QListWidgetItem; |
|
||||||
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) |
|
||||||
delete takeItem(nbLines - 1); |
|
||||||
} |
|
||||||
|
|
||||||
void LogListWidget::copySelection() |
|
||||||
{ |
|
||||||
const QRegularExpression htmlTag("<[^>]+>"); |
|
||||||
|
|
||||||
QStringList strings; |
|
||||||
for (QListWidgetItem *it : asConst(selectedItems())) |
|
||||||
strings << static_cast<QLabel*>(itemWidget(it))->text().remove(htmlTag); |
|
||||||
|
|
||||||
QApplication::clipboard()->setText(strings.join('\n')); |
|
||||||
} |
|
Loading…
Reference in new issue