File indexing completed on 2024-11-24 04:50:45

0001 // SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
0002 // SPDX-License-Identifier: LGPL-2.1-or-later
0003 
0004 #include "tagmanager.h"
0005 #include "akonadi_quick_debug.h"
0006 
0007 #include <Akonadi/TagCreateJob>
0008 #include <Akonadi/TagDeleteJob>
0009 #include <Akonadi/TagModifyJob>
0010 #include <KDescendantsProxyModel>
0011 
0012 class FlatTagModel : public QSortFilterProxyModel
0013 {
0014 public:
0015     explicit FlatTagModel(QObject *parent = nullptr)
0016         : QSortFilterProxyModel(parent)
0017     {
0018         auto monitor = new Akonadi::Monitor(this);
0019         monitor->setObjectName(QLatin1StringView("TagModelMonitor"));
0020         monitor->setTypeMonitored(Akonadi::Monitor::Tags);
0021 
0022         auto flatTagModel = new KDescendantsProxyModel;
0023         flatTagModel->setSourceModel(new Akonadi::TagModel(monitor));
0024         setSourceModel(flatTagModel);
0025 
0026         setDynamicSortFilter(true);
0027         sort(0);
0028     }
0029 
0030     QHash<int, QByteArray> roleNames() const override
0031     {
0032         auto rolenames = QSortFilterProxyModel::roleNames();
0033         rolenames[Akonadi::TagModel::Roles::NameRole] = QByteArrayLiteral("name");
0034         rolenames[Akonadi::TagModel::Roles::IdRole] = QByteArrayLiteral("id");
0035         rolenames[Akonadi::TagModel::Roles::GIDRole] = QByteArrayLiteral("gid");
0036         rolenames[Akonadi::TagModel::Roles::TypeRole] = QByteArrayLiteral("type");
0037         rolenames[Akonadi::TagModel::Roles::ParentRole] = QByteArrayLiteral("parent");
0038         rolenames[Akonadi::TagModel::Roles::TagRole] = QByteArrayLiteral("tag");
0039 
0040         return rolenames;
0041     }
0042 
0043 protected:
0044     bool filterAcceptsRow(int row, const QModelIndex &sourceParent) const override
0045     {
0046         // Eliminate duplicate tag names
0047         const QModelIndex sourceIndex = sourceModel()->index(row, 0, sourceParent);
0048         Q_ASSERT(sourceIndex.isValid());
0049 
0050         auto data = sourceIndex.data(Akonadi::TagModel::NameRole);
0051         auto matches = match(index(0, 0), Akonadi::TagModel::NameRole, data, 2, Qt::MatchExactly | Qt::MatchWrap | Qt::MatchRecursive);
0052 
0053         return matches.length() < 2;
0054     }
0055 };
0056 
0057 TagManager::TagManager(QObject *parent)
0058     : QObject(parent)
0059 {
0060     m_tagModel = new FlatTagModel(this);
0061 
0062     QObject::connect(m_tagModel, &QSortFilterProxyModel::dataChanged, this, &TagManager::tagModelChanged);
0063     QObject::connect(m_tagModel, &QSortFilterProxyModel::layoutChanged, this, &TagManager::tagModelChanged);
0064     QObject::connect(m_tagModel, &QSortFilterProxyModel::modelReset, this, &TagManager::tagModelChanged);
0065     QObject::connect(m_tagModel, &QSortFilterProxyModel::rowsInserted, this, &TagManager::tagModelChanged);
0066     QObject::connect(m_tagModel, &QSortFilterProxyModel::rowsMoved, this, &TagManager::tagModelChanged);
0067     QObject::connect(m_tagModel, &QSortFilterProxyModel::rowsRemoved, this, &TagManager::tagModelChanged);
0068 }
0069 
0070 QSortFilterProxyModel *TagManager::tagModel()
0071 {
0072     return m_tagModel;
0073 }
0074 
0075 void TagManager::createTag(const QString &name)
0076 {
0077     Akonadi::Tag tag(name);
0078     auto job = new Akonadi::TagCreateJob(tag, this);
0079     connect(job, &Akonadi::TagCreateJob::finished, this, [](KJob *job) {
0080         if (job->error())
0081             qCDebug(AKONADI_QUICK_LOG) << "Error occurred creating tag";
0082     });
0083 }
0084 
0085 void TagManager::deleteTag(Akonadi::Tag tag)
0086 {
0087     auto job = new Akonadi::TagDeleteJob(tag);
0088     connect(job, &Akonadi::TagDeleteJob::result, this, [](KJob *job) {
0089         if (job->error())
0090             qCDebug(AKONADI_QUICK_LOG) << "Error occurred renaming tag";
0091     });
0092 }
0093 
0094 void TagManager::renameTag(Akonadi::Tag tag, const QString &newName)
0095 {
0096     tag.setName(newName);
0097     auto job = new Akonadi::TagModifyJob(tag);
0098     connect(job, &Akonadi::TagModifyJob::result, this, [](KJob *job) {
0099         if (job->error())
0100             qCDebug(AKONADI_QUICK_LOG) << "Error occurred renaming tag";
0101     });
0102 }
0103 
0104 #include "moc_tagmanager.cpp"