File indexing completed on 2024-05-19 05:11:19

0001 /*
0002   SPDX-FileCopyrightText: 2012 Sérgio Martins <iamsergio@gmail.com>
0003 
0004   SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
0005 */
0006 
0007 #pragma once
0008 
0009 #include "incidencetreemodel.h"
0010 
0011 #include <Akonadi/Item>
0012 
0013 #include <KCalendarCore/Incidence>
0014 #include <QHash>
0015 #include <QList>
0016 #include <QModelIndex>
0017 #include <QObject>
0018 #include <QPersistentModelIndex>
0019 #include <QSharedPointer>
0020 #include <QStringList>
0021 
0022 namespace Akonadi
0023 {
0024 using Uid = QString;
0025 using ParentUid = QString;
0026 
0027 struct Node {
0028     using Ptr = QSharedPointer<Node>;
0029     using Map = QMap<Akonadi::Item::Id, Ptr>;
0030     using List = QList<Ptr>;
0031 
0032     QPersistentModelIndex sourceIndex; // because ETM::modelIndexesForItem is so slow
0033     Akonadi::Item::Id id;
0034     Node::Ptr parentNode;
0035     QString parentUid;
0036     QString uid;
0037     List directChilds;
0038     int depth;
0039 };
0040 
0041 /** Just a struct to contain some data before we create the node */
0042 struct PreNode {
0043     using Ptr = QSharedPointer<PreNode>;
0044     using List = QList<Ptr>;
0045     KCalendarCore::Incidence::Ptr incidence;
0046     QPersistentModelIndex sourceIndex;
0047     Akonadi::Item item;
0048     int depth;
0049     PreNode()
0050         : depth(-1)
0051     {
0052     }
0053 };
0054 
0055 class IncidenceTreeModelPrivate : public QObject
0056 {
0057     Q_OBJECT
0058 public:
0059     IncidenceTreeModelPrivate(IncidenceTreeModel *qq, const QStringList &mimeTypes);
0060     void reset(bool silent = false);
0061     void insertNode(const PreNode::Ptr &node, bool silent = false);
0062     void insertNode(const QModelIndex &sourceIndex, bool silent = false);
0063     void removeNode(const Node::Ptr &node);
0064     QModelIndex indexForNode(const Node::Ptr &node) const;
0065     int rowForNode(const Node::Ptr &node) const;
0066     bool indexBeingRemoved(const QModelIndex &) const; // Is it being removed?
0067     void dumpTree();
0068     void assert_and_dump(bool condition, const QString &message);
0069     Node::List sorted(const Node::List &nodes) const;
0070     PreNode::Ptr prenodeFromSourceRow(int sourceRow) const;
0071     void setSourceModel(QAbstractItemModel *model);
0072 
0073 public:
0074     Node::Map m_nodeMap;
0075     Node::List m_toplevelNodeList;
0076     QHash<Uid, Node::Ptr> m_uidMap;
0077     QHash<Uid, Akonadi::Item> m_itemByUid;
0078     QMultiHash<ParentUid, Node::Ptr> m_waitingForParent;
0079     QList<Node *> m_removedNodes;
0080     const QStringList m_mimeTypes;
0081 
0082 private Q_SLOTS:
0083     void onHeaderDataChanged(Qt::Orientation orientation, int first, int last);
0084     void onDataChanged(const QModelIndex &begin, const QModelIndex &end);
0085 
0086     void onRowsAboutToBeInserted(const QModelIndex &parent, int begin, int end);
0087     void onRowsInserted(const QModelIndex &parent, int begin, int end);
0088     void onRowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
0089     void onRowsRemoved(const QModelIndex &parent, int begin, int end);
0090     void onRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
0091 
0092     void onModelAboutToBeReset();
0093     void onModelReset();
0094     void onLayoutAboutToBeChanged();
0095     void onLayoutChanged();
0096 
0097 private:
0098     IncidenceTreeModel *const q;
0099 };
0100 }