Mike Tzou
5 years ago
committed by
GitHub
14 changed files with 610 additions and 195 deletions
@ -0,0 +1,52 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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