File indexing completed on 2024-05-05 05:48:57

0001 /*
0002     SPDX-FileCopyrightText: 2007 Nicolas Ternisien <nicolas.ternisien@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "logViewFilterWidget.h"
0008 #include "ksystemlog_debug.h"
0009 #include "logLevel.h"
0010 #include "logViewColumn.h"
0011 #include "logViewWidget.h"
0012 
0013 #include <QHBoxLayout>
0014 #include <QLabel>
0015 #include <QPushButton>
0016 #include <QString>
0017 
0018 #include <QComboBox>
0019 #include <QMetaEnum>
0020 #include <QStandardItemModel>
0021 #include <QStyledItemDelegate>
0022 
0023 #include <KLocalizedString>
0024 
0025 class ComboBoxDelegate : public QStyledItemDelegate
0026 {
0027 public:
0028     explicit ComboBoxDelegate(QWidget *parent)
0029         : QStyledItemDelegate(parent)
0030     {
0031     }
0032 
0033     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
0034     {
0035         auto &refToNonConstOption = const_cast<QStyleOptionViewItem &>(option);
0036         refToNonConstOption.showDecorationSelected = false;
0037         QStyledItemDelegate::paint(painter, refToNonConstOption, index);
0038     }
0039 };
0040 
0041 class LogViewFilterWidgetPrivate
0042 {
0043 public:
0044 };
0045 
0046 LogViewWidgetSearchLine::LogViewWidgetSearchLine(QWidget *parent)
0047     : KTreeWidgetSearchLine(parent)
0048 {
0049     for (int i = 0; i < Globals::LOG_LEVEL_NUM; i++) {
0050         mPriorities[i] = true;
0051     }
0052 }
0053 
0054 LogViewWidgetSearchLine::~LogViewWidgetSearchLine()
0055 {
0056 }
0057 
0058 void LogViewWidgetSearchLine::updateSearch(const QString &pattern)
0059 {
0060     KTreeWidgetSearchLine::updateSearch(pattern);
0061 
0062     Q_EMIT treeWidgetUpdated();
0063 }
0064 
0065 void LogViewWidgetSearchLine::setPriorityEnabled(int priority, bool enabled)
0066 {
0067     if ((priority < 0) || (priority >= Globals::LOG_LEVEL_NUM)) {
0068         return;
0069     }
0070     mPriorities[priority] = enabled;
0071     updateSearch(QString());
0072 }
0073 
0074 bool LogViewWidgetSearchLine::itemMatches(const QTreeWidgetItem *item, const QString &pattern) const
0075 {
0076     // Hide item if its priority is not enabled.
0077     const int priority = item->data(0, Qt::UserRole).toInt();
0078     if ((priority >= 0) && (priority < Globals::LOG_LEVEL_NUM)) {
0079         if (!mPriorities[priority]) {
0080             return false;
0081         }
0082     }
0083     return KTreeWidgetSearchLine::itemMatches(item, pattern);
0084 }
0085 
0086 LogViewFilterWidget::LogViewFilterWidget(QWidget *parent)
0087     : QWidget(parent)
0088 {
0089     auto filterBarLayout = new QHBoxLayout(this);
0090     filterBarLayout->setContentsMargins(0, 0, 0, 0);
0091 
0092     mFilterLine = new LogViewWidgetSearchLine();
0093 
0094     mFilterLine->setToolTip(i18n("Type your filter here"));
0095     mFilterLine->setWhatsThis(i18n("Allows you to only list items that match the content of this text."));
0096     mFilterLine->setPlaceholderText(i18n("Enter your search here..."));
0097 
0098     auto filterIcon = new QLabel();
0099     filterIcon->setPixmap(QIcon::fromTheme(QStringLiteral("view-filter")).pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize)));
0100     filterIcon->setBuddy(mFilterLine);
0101     filterBarLayout->addWidget(filterIcon);
0102 
0103     auto filterLabel = new QLabel(i18n("Filter:"));
0104     filterLabel->setBuddy(mFilterLine);
0105     filterBarLayout->addWidget(filterLabel);
0106 
0107     filterBarLayout->addWidget(mFilterLine);
0108 
0109     initSearchListFilter();
0110 
0111     filterBarLayout->addWidget(mFilterList);
0112 
0113     mPrioritiesComboBox = new QComboBox(this);
0114     auto delegate = new ComboBoxDelegate(mPrioritiesComboBox);
0115     mPrioritiesComboBox->setItemDelegate(delegate);
0116     filterBarLayout->addWidget(mPrioritiesComboBox);
0117 
0118     QMetaEnum const &metaEnum = Globals::instance().logLevelsMetaEnum();
0119 
0120     mPrioritiesModel = new QStandardItemModel(mPrioritiesComboBox);
0121     mPrioritiesComboBox->setModel(mPrioritiesModel);
0122 
0123     auto item = new QStandardItem(i18n("Select priorities"));
0124     item->setSelectable(false);
0125     mPrioritiesModel->appendRow(item);
0126     connect(mPrioritiesModel, &QStandardItemModel::itemChanged, this, &LogViewFilterWidget::prioritiesChanged);
0127 
0128     // Don't add last enum value into combobox.
0129     for (int i = 0; i < metaEnum.keyCount() - 1; i++) {
0130         const int id = metaEnum.value(i);
0131         LogLevel *logLevel = Globals::instance().logLevelByPriority(id);
0132 
0133         auto item = new QStandardItem(logLevel->name());
0134         item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
0135         item->setData(Qt::Checked, Qt::CheckStateRole);
0136         item->setData(metaEnum.value(i), Qt::UserRole);
0137         item->setData(QVariant(logLevel->color()), Qt::ForegroundRole);
0138 
0139         mPrioritiesModel->appendRow(item);
0140     }
0141 }
0142 
0143 LogViewFilterWidget::~LogViewFilterWidget()
0144 {
0145 }
0146 
0147 void LogViewFilterWidget::initSearchListFilter()
0148 {
0149     mFilterList = new QComboBox();
0150 
0151     mFilterList->setToolTip(i18n("Choose the filtered column here"));
0152     mFilterList->setWhatsThis(
0153         i18n("Allows you to apply the item filter only on the specified column here. \"<i>All</i>\" column means "
0154              "no specific filter."));
0155 
0156     mFilterList->addItem(i18n("All"));
0157 
0158     mFilterList->setSizeAdjustPolicy(QComboBox::AdjustToContents);
0159 
0160     connect(mFilterList, SIGNAL(activated(int)), mFilterLine, SLOT(setFocus()));
0161     connect(mFilterList, &QComboBox::activated, this, &LogViewFilterWidget::changeColumnFilter);
0162     connect(mFilterList, SIGNAL(activated(int)), mFilterLine, SLOT(updateSearch()));
0163 }
0164 
0165 void LogViewFilterWidget::updateFilterColumns(const LogViewColumns &columns)
0166 {
0167     qCDebug(KSYSTEMLOG) << "Changing columns...";
0168 
0169     // We first delete all items
0170     mFilterList->clear();
0171 
0172     // Then we insert the default items
0173     mFilterList->addItem(i18n("All"));
0174 
0175     const auto cols = columns.columns();
0176     for (const LogViewColumn &column : cols) {
0177         if (column.isFiltered()) {
0178             mFilterList->addItem(column.columnName());
0179         }
0180     }
0181 
0182     mFilterList->setCurrentIndex(0);
0183 }
0184 
0185 void LogViewFilterWidget::changeColumnFilter(int column)
0186 {
0187     // The user select all columns
0188     if (column == 0) {
0189         qCDebug(KSYSTEMLOG) << "Searching on all columns";
0190 
0191         mFilterLine->setSearchColumns(QList<int>());
0192         return;
0193     }
0194 
0195     qCDebug(KSYSTEMLOG) << "Searching on " << mFilterList->currentIndex() << " column";
0196 
0197     // currentIndex() - 1 to do not count the "All" columns item
0198     const QList<int> filterColumns{mFilterList->currentIndex() - 1};
0199 
0200     mFilterLine->setSearchColumns(filterColumns);
0201 }
0202 
0203 void LogViewFilterWidget::prioritiesChanged(QStandardItem *item)
0204 {
0205     const int priority = item->data(Qt::UserRole).toInt();
0206     const bool priorityEnabled = (item->checkState() == Qt::Checked);
0207     mFilterLine->setPriorityEnabled(priority, priorityEnabled);
0208     if (priorityEnabled) {
0209         qCDebug(KSYSTEMLOG) << "Show entries with priority" << priority;
0210     } else {
0211         qCDebug(KSYSTEMLOG) << "Hide entries with priority" << priority;
0212     }
0213 }
0214 
0215 QComboBox *LogViewFilterWidget::filterList() const
0216 {
0217     return mFilterList;
0218 }
0219 
0220 LogViewWidgetSearchLine *LogViewFilterWidget::filterLine() const
0221 {
0222     return mFilterLine;
0223 }
0224 
0225 #include "moc_logViewFilterWidget.cpp"