2026-08-24 01:04:00 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <QAbstractItemModel>
|
|
|
|
|
#include <QModelIndex>
|
|
|
|
|
#include <QVariant>
|
|
|
|
|
#include <QVector>
|
|
|
|
|
#include <QDateTime>
|
|
|
|
|
#include <QDate>
|
|
|
|
|
#include "core/mailitem.h"
|
|
|
|
|
|
|
|
|
|
class EmailTreeModel : public QAbstractItemModel
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
enum Columns {
|
|
|
|
|
ColSubject = 0,
|
|
|
|
|
ColSender = 1,
|
|
|
|
|
ColDate = 2,
|
|
|
|
|
ColCount = 3
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum Roles {
|
|
|
|
|
MailIdRole = Qt::UserRole + 1,
|
|
|
|
|
IsGroupRole = Qt::UserRole + 2,
|
|
|
|
|
GroupNameRole = Qt::UserRole + 3,
|
|
|
|
|
GroupIndexRole = Qt::UserRole + 4,
|
2026-08-25 18:53:51 +02:00
|
|
|
MailIndexRole = Qt::UserRole + 5,
|
|
|
|
|
IsThreadRole = Qt::UserRole + 6,
|
|
|
|
|
ThreadIdRole = Qt::UserRole + 7,
|
|
|
|
|
IsThreadExpandedRole = Qt::UserRole + 8
|
2026-08-24 01:04:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
explicit EmailTreeModel(QObject *parent = nullptr);
|
|
|
|
|
~EmailTreeModel() override;
|
|
|
|
|
|
|
|
|
|
// Basic model interface
|
|
|
|
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
|
|
|
|
QModelIndex parent(const QModelIndex &child) const override;
|
|
|
|
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
|
|
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
|
|
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
|
|
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
|
|
|
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
|
|
|
|
|
|
|
|
|
// Email data management
|
|
|
|
|
void setEmails(const QVector<MailItem> &emails);
|
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
|
|
// Grouping
|
|
|
|
|
enum GroupMode {
|
|
|
|
|
NoGrouping = 0,
|
2026-08-25 18:53:51 +02:00
|
|
|
GroupByDate = 1,
|
|
|
|
|
GroupByThread = 2,
|
|
|
|
|
GroupBySender = 3
|
2026-08-24 01:04:00 +02:00
|
|
|
};
|
|
|
|
|
void setGroupMode(GroupMode mode);
|
|
|
|
|
GroupMode groupMode() const { return m_groupMode; }
|
|
|
|
|
|
2026-08-25 18:53:51 +02:00
|
|
|
// Thread expansion
|
|
|
|
|
void setThreadExpanded(const QString& threadId, bool expanded);
|
|
|
|
|
bool isThreadExpanded(const QString& threadId) const;
|
|
|
|
|
|
2026-08-24 01:04:00 +02:00
|
|
|
private:
|
|
|
|
|
struct TreeItem {
|
2026-08-25 18:53:51 +02:00
|
|
|
enum Type { Group, Mail, Thread } type;
|
2026-08-24 01:04:00 +02:00
|
|
|
QString groupName; // for Group type
|
2026-08-25 18:53:51 +02:00
|
|
|
QString threadId; // for Thread type
|
2026-08-24 01:04:00 +02:00
|
|
|
int groupIndex = -1; // for Group type
|
|
|
|
|
int mailIndex = -1; // for Mail type (index in m_emails)
|
|
|
|
|
QVector<TreeItem*> children;
|
|
|
|
|
TreeItem* parent = nullptr;
|
|
|
|
|
int row = -1;
|
2026-08-25 18:53:51 +02:00
|
|
|
bool expanded = true; // for Thread type
|
2026-08-24 01:04:00 +02:00
|
|
|
|
|
|
|
|
TreeItem(Type t, TreeItem* p = nullptr) : type(t), parent(p) {}
|
|
|
|
|
~TreeItem() { qDeleteAll(children); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GroupMode m_groupMode = NoGrouping;
|
|
|
|
|
QVector<MailItem> m_emails;
|
|
|
|
|
TreeItem* m_rootItem = nullptr;
|
2026-08-25 18:53:51 +02:00
|
|
|
QSet<QString> m_expandedThreads;
|
2026-08-24 01:04:00 +02:00
|
|
|
|
|
|
|
|
void setupModelData();
|
|
|
|
|
void buildGroups();
|
2026-08-25 18:53:51 +02:00
|
|
|
void buildThreads();
|
|
|
|
|
void buildSenderGroups();
|
2026-08-24 01:04:00 +02:00
|
|
|
QString groupNameForDate(const QDateTime &date) const;
|
|
|
|
|
int groupIndexForDate(const QDateTime &date) const;
|
|
|
|
|
void deleteTree(TreeItem* item);
|
2026-08-25 18:53:51 +02:00
|
|
|
void buildThreadTree();
|
|
|
|
|
QString extractThreadId(const MailItem& mail) const;
|
2026-08-24 01:04:00 +02:00
|
|
|
};
|