File indexing completed on 2024-05-12 05:12:46
0001 /* 0002 SPDX-FileCopyrightText: 2018 Daniel Vrátil <dvratil@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "loggingmodel.h" 0008 0009 #include <KLocalizedString> 0010 0011 #include <QDateTime> 0012 #include <QDir> 0013 #include <QStandardItemModel> 0014 0015 Q_DECLARE_METATYPE(LoggingModel::Message) 0016 0017 LoggingModel::LoggingModel(QObject *parent) 0018 : QAbstractItemModel(parent) 0019 { 0020 } 0021 0022 LoggingModel::~LoggingModel() = default; 0023 0024 QString LoggingModel::cacheString(const QString &str, QSet<QString> &cache, QStandardItemModel *model) 0025 { 0026 auto it = cache.constFind(str); 0027 if (it == cache.constEnd()) { 0028 if (model) { 0029 auto item = new QStandardItem(str); 0030 item->setCheckState(Qt::Checked); 0031 model->appendRow(item); 0032 } 0033 cache.insert(str); 0034 return str; 0035 } 0036 return *it; 0037 } 0038 0039 void LoggingModel::addMessage(qint64 timestamp, 0040 const QString &app, 0041 qint64 pid, 0042 QtMsgType type, 0043 const QString &category, 0044 const QString &file, 0045 const QString &function, 0046 int line, 0047 const QString &message) 0048 { 0049 beginInsertRows({}, mMessages.count(), mMessages.count()); 0050 mMessages.push_back({timestamp, 0051 cacheString(app, mAppCache, mAppFilterModel), 0052 pid, 0053 cacheString(category, mCategoryCache, mCategoryFilterModel), 0054 cacheString(file, mFileCache), 0055 cacheString(function, mFunctionCache), 0056 message, 0057 type, 0058 line}); 0059 endInsertRows(); 0060 } 0061 0062 void LoggingModel::setAppFilterModel(QStandardItemModel *appFilterModel) 0063 { 0064 mAppFilterModel = appFilterModel; 0065 } 0066 0067 void LoggingModel::setCategoryFilterModel(QStandardItemModel *categoryFilterModel) 0068 { 0069 mCategoryFilterModel = categoryFilterModel; 0070 } 0071 0072 int LoggingModel::rowCount(const QModelIndex &parent) const 0073 { 0074 return parent.isValid() ? 0 : mMessages.count(); 0075 } 0076 0077 int LoggingModel::columnCount(const QModelIndex &) const 0078 { 0079 return _ColumnCount; 0080 } 0081 0082 QModelIndex LoggingModel::index(int row, int column, const QModelIndex &parent) const 0083 { 0084 if (parent.isValid() || row < 0 || row >= mMessages.count() || column < 0 || column >= _ColumnCount) { 0085 return {}; 0086 } 0087 0088 return createIndex(row, column); 0089 } 0090 0091 QModelIndex LoggingModel::parent(const QModelIndex &) const 0092 { 0093 return {}; 0094 } 0095 0096 QVariant LoggingModel::headerData(int section, Qt::Orientation orientation, int role) const 0097 { 0098 if (orientation != Qt::Horizontal || role != Qt::DisplayRole) { 0099 return {}; 0100 } 0101 0102 switch (section) { 0103 case TimeColumn: 0104 return i18n("Time"); 0105 case AppColumn: 0106 return i18n("Program"); 0107 case TypeColumn: 0108 return i18n("Type"); 0109 case CategoryColumn: 0110 return i18n("Category"); 0111 case FileColumn: 0112 return i18n("File"); 0113 case FunctionColumn: 0114 return i18n("Function"); 0115 case MessageColumn: 0116 return i18n("Message"); 0117 } 0118 return {}; 0119 } 0120 0121 QVariant LoggingModel::data(const QModelIndex &index, int role) const 0122 { 0123 if (!index.isValid() || index.row() >= mMessages.count() || index.column() >= _ColumnCount) { 0124 return {}; 0125 } 0126 0127 const auto message = mMessages.at(index.row()); 0128 if (role == Qt::DisplayRole) { 0129 switch (index.column()) { 0130 case TimeColumn: 0131 return QDateTime::fromMSecsSinceEpoch(message.timestamp).toString(Qt::ISODateWithMs); 0132 case AppColumn: 0133 return QStringLiteral("%1(%2)").arg(message.app, QString::number(message.pid)); 0134 case TypeColumn: 0135 switch (message.type) { 0136 case QtDebugMsg: 0137 return i18n("Debug"); 0138 case QtInfoMsg: 0139 return i18n("Info"); 0140 case QtWarningMsg: 0141 return i18n("Warning"); 0142 case QtCriticalMsg: 0143 return i18n("Critical"); 0144 case QtFatalMsg: 0145 return i18n("Fatal"); 0146 } 0147 return {}; 0148 case CategoryColumn: 0149 return message.category; 0150 case FileColumn: 0151 if (!message.file.isEmpty()) { 0152 const auto file = message.file.mid(message.file.lastIndexOf(QDir::separator()) + 1, -1); 0153 if (message.line > 0) { 0154 return i18n("%1:%2", file, QString::number(message.line)); 0155 } else { 0156 return file; 0157 } 0158 } 0159 return {}; 0160 case FunctionColumn: 0161 return message.function; 0162 case MessageColumn: 0163 return message.message; 0164 } 0165 } else if (role == Qt::ToolTipRole) { 0166 switch (index.column()) { 0167 case FileColumn: 0168 if (!message.file.isEmpty()) { 0169 if (message.line > 0) { 0170 return i18n("%1:%2", message.file, QString::number(message.line)); 0171 } else { 0172 return message.file; 0173 } 0174 } 0175 return {}; 0176 case FunctionColumn: 0177 return message.function; 0178 case MessageColumn: 0179 return message.message; 0180 } 0181 } else if (role == MessageRole) { 0182 return QVariant::fromValue(message); 0183 } 0184 0185 return {}; 0186 } 0187 0188 #include "moc_loggingmodel.cpp"