File indexing completed on 2024-05-12 05:12:47

0001 /*
0002  * <one line to give the library's name and an idea of what it does.>
0003  * SPDX-FileCopyrightText: 2018 David Faure <faure@kde.org>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006  */
0007 
0008 #include "notificationfiltermodel.h"
0009 #include "notificationmodel.h"
0010 
0011 #include <Libkdepim/KCheckComboBox>
0012 #include <QStandardItemModel>
0013 #include <chrono>
0014 
0015 using namespace std::chrono_literals;
0016 
0017 using KPIM::KCheckComboBox;
0018 
0019 Q_DECLARE_METATYPE(Akonadi::ChangeNotification)
0020 
0021 NotificationFilterModel::NotificationFilterModel(QObject *parent)
0022     : QSortFilterProxyModel(parent)
0023 {
0024     mInvalidateTimer.setInterval(50ms);
0025     mInvalidateTimer.setSingleShot(true);
0026     connect(&mInvalidateTimer, &QTimer::timeout, this, &NotificationFilterModel::invalidateFilter);
0027 }
0028 
0029 NotificationFilterModel::~NotificationFilterModel() = default;
0030 
0031 void NotificationFilterModel::setTypeFilter(KPIM::KCheckComboBox *typeFilter)
0032 {
0033     if (mTypeFilter) {
0034         mTypeFilter->disconnect(this);
0035     }
0036     mTypeFilter = typeFilter;
0037     connect(mTypeFilter, &KCheckComboBox::checkedItemsChanged, this, [this](const QStringList &items) {
0038         mCheckedTypes.clear();
0039         mCheckedTypes.reserve(items.count());
0040         // it sucks a bit that KCheckComboBox::checkedItems can't return a QVariantList instead of a QStringList
0041         for (const QString &item : mTypeFilter->checkedItems(Qt::UserRole)) {
0042             mCheckedTypes.insert(static_cast<Akonadi::ChangeNotification::Type>(item.toInt()));
0043         }
0044         if (!mInvalidateTimer.isActive()) {
0045             mInvalidateTimer.start();
0046         }
0047     });
0048 }
0049 
0050 bool NotificationFilterModel::filterAcceptsRow(int source_row, const QModelIndex &) const
0051 {
0052     const auto source_idx = sourceModel()->index(source_row, 0);
0053     const auto notification = sourceModel()->data(source_idx, NotificationModel::NotificationRole).value<Akonadi::ChangeNotification>();
0054     return mCheckedTypes.contains(notification.type());
0055 }
0056 
0057 void NotificationFilterModel::setSourceModel(QAbstractItemModel *model)
0058 {
0059     if (sourceModel()) {
0060         disconnect(sourceModel(), &QAbstractItemModel::rowsInserted, this, &NotificationFilterModel::slotRowsInserted);
0061     }
0062     connect(model, &QAbstractItemModel::rowsInserted, this, &NotificationFilterModel::slotRowsInserted);
0063     QSortFilterProxyModel::setSourceModel(model);
0064 }
0065 
0066 void NotificationFilterModel::slotRowsInserted(const QModelIndex &source_parent, int start, int end)
0067 {
0068     // insert new types (if any) into the type filter combo
0069     Q_ASSERT(!source_parent.isValid());
0070     for (int row = start; row <= end; ++row) {
0071         const QModelIndex source_idx = sourceModel()->index(start, NotificationModel::TypeColumn);
0072         const QString text = source_idx.data().toString();
0073         if (!mTypes.contains(text)) {
0074             mTypes.insert(text);
0075             auto comboModel = qobject_cast<QStandardItemModel *>(mTypeFilter->model());
0076             Q_ASSERT(comboModel);
0077             auto item = new QStandardItem(text);
0078             const auto notification = sourceModel()->data(source_idx, NotificationModel::NotificationRole).value<Akonadi::ChangeNotification>();
0079             item->setData(int(notification.type()), Qt::UserRole);
0080             item->setCheckState(Qt::Checked);
0081             comboModel->appendRow(item);
0082         }
0083     }
0084 }
0085 
0086 #include "moc_notificationfiltermodel.cpp"