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"